数组和集合的区别:
1、数组的长度是固定的,集合的长度是可变的
2、数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象,而且对象的类型可以不一致。
Collection:所以单列集合的父接口,定义了单列集合通用的一些方法
示例代码:
public class Demo {
public static void main(String [] args) {
Collection<String> coll = new ArrayList<>();
System.out.println(coll);
boolean b1=coll.add("读者A");
boolean b2=coll.add("读者B");
System.out.println(coll);
boolean b3=coll.remove("读者C");
boolean b4=coll.remove("读者B");
boolean b5=coll.contains("读者A");
boolean b6=coll.isEmpty();
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
System.out.println(b5);
System.out.println(b6);
System.out.println(coll.size());
System.out.println(coll.toArray()[0]);
}
}
iterator :迭代器接口,迭代,就是collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续判断,如果还有就再取出来,一直到集合中的所有元素都取出。
示例代码:
public class Demo {
public static void main(String [] args) {
Collection<String> coll = new ArrayList<>();
System.out.println(coll);
boolean b1=coll.add("读者A");
boolean b2=coll.add("读者B");
Iterator<String> it = coll.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
增强for循环:底层使用迭代器,使用for循环的格式,简化迭代器书写,用来遍历集合和数组
格式 : for(集合/数组的数据类型 变量名 : 集合名/数组名){方法体}
示例代码:
public class Demo {
public static void main(String [] args) {
Collection<String> coll = new ArrayList<>();
System.out.println(coll);
boolean b1=coll.add("读者A");
boolean b2=coll.add("读者B");
for (String str:coll) {
System.out.println(str);
}
}
}
注意:增强for循环的目标只能是集合或者数组
泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型 E e :Element 元素 ,T t :Type 类型
创建集合,不使用泛型:
好处:集合不使用泛型,默认类型就是Object类型,可以存储任意类型的数据
坏处:不安全,容易引发异常
创建集合,使用泛型:
好处:1、避免了类型转换的麻烦,存储的是什么数据,取出的就是什么类型
2、把运行期间的异常提升到了编译期间
坏处:泛型是什么类型,只能存储什么类型的数据
定义一个泛型的类:修饰符 class 类名<代表泛型的变量>{}
定义一个泛型的方法: 修饰符 <泛型> 返回值类型 方法名 (参数列表(使用泛型)){方法体},含有泛型的方法在调用方法的时候确定泛型的数据类型,参数传递什么类型,泛型就是什么类型
定义一个泛型的接口: 修饰符 interface 接口名<泛型>{}
含义泛型的接口的使用方式:1、定义接口的实现类,实行接口,指定接口的泛型
2、接口使用什么泛型,实现类就使用什么泛型
泛型通配符:当使用泛型类或者接口时,传递的数据中,泛型的类型不确定,可以通过通配符<?>表示。但是一旦使用了泛型通配符后,只能使用Object类中的共性方法,集合中的元素自身方法无法使用
示例代码
public class Demo {
public static void main(String[] args){}
private class Demo2<E>{
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
public <M> void method(M m){
}
public void printArray(ArrayList<?> list){
Iterator<?>it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
}
List接口:1、他是一个元素存取有序的集合
2、他是一个带有索引的集合
3、集合中可以有重复的元素
注意:要防止索引的越界异常
示例代码
public class Demo {
public static void main(String[] args){
List<String> list =new ArrayList<>();
list.add("读者A");
list.add("读者B");
list.add("读者A");
System.out.println(list);
list.add(1,"读者C");
System.out.println(list);
list.remove(1);
System.out.println(list);
list.set(1,"读者D");
System.out.println(list);
}
}
ArrayList:前面已经用过,不再讲述,底层是数组数据结构
LinkedList:链表数据结构
示例代码
public class Demo {
public static void main(String[] args){
LinkedList<String> list = new LinkedList<>();
list.add("读者A");
list.add("读者B");
list.add("读者A");
System.out.println(list);
list.addFirst("读者C");
System.out.println(list);
list.addLast("读者D");
System.out.println(list);
list.push("读者E");
System.out.println(list);
list.pop();
System.out.println(list);
System.out.println(list.getFirst());
System.out.println(list.getLast());
list.removeFirst();
list.removeLast();
}
}
Vector:底层是数组数据结构,现在多用ArrayList代替使用
Set接口类:1、不允许存储重复的元素
2、没有索引,没有带索引的方法,也不能使用普通的for循环遍历
HashSet实现类:1、不允许存储重复的元素
2、没有索引,没有带索引的方法,也不能使用普通的for循环遍历
3、是一个无序的集合,存储元素和取出元素的顺序有可能不一致
4、底层是一个哈希表结构(查询的速度非常的快)
示例代码:
public class Demo {
public static void main(String[] args){
Set<Integer> set = new HashSet<>();
set.add(96);
set.add(97);
set.add(98);
set.add(99);
set.add(100);
set.add(97);
System.out.println(set);
Iterator it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
扩展:哈希值,是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)
注意:使用HashSet存储自定义类型的元素时,要重写hashCode和equals方法
LinkedHashSet:HashSet的子类,元素不可以重复,但是有序,底层是一个哈希表+链表
示例代码:
public class Demo {
public static void main(String[] args){
LinkedHashSet<Integer> set = new LinkedHashSet<>();
set.add(96);
set.add(97);
set.add(98);
set.add(99);
set.add(97);
System.out.println(set);
Iterator it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
可变参数:当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数 , 修饰符 返回值类型 方法名(数据类型...变量名){},可变参数底层就是一个数组,根据传递的参数个数不同,会创建不同长度的数组,来存储这些参数。
public class Demo {
public static void main(String[] args){
System.out.println(sum(1,2,3));
System.out.println(sum(1,2));
}
public static int sum (int...a){
int sum =0;
for (int b:a) {
sum+=b;
}
return sum;
}
}
Collections:操作集合的工具类,对集合进行操作
示例代码:
public class Demo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(96);
list.add(97);
list.add(98);
list.add(99);
list.add(100);
Collections.shuffle(list);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
}
Map集合接口:1、Map集合是一个双列集合,一个元素包含两个值(Key,Value)
2、Map集合中的元素,Key和Value的数据类型可以相同也可以不同
3、Map集合中的元素,Key是不允许重复的,Value是可以重复的
4、Map集合中的元素,Key和Value是一一对应的
HashMap<K,V>,Map接口的实现类:1、底层是哈希表,查询速度快
2、是一个无序的集合,存储元素和取出元素的顺序不一致
LinkedHashMap<K,V>,HashMap的子类:1、底层是哈希表+链表
2、集合是一个有序的集合,存储元素和取出元素的顺序一致
Map接口的示例代码
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("读者A","作品A");
map.put("读者B","作品B");
map.put("读者C","作品C");
map.put("读者D","作品D");
System.out.println(map);
map.remove("读者D");
System.out.println(map);
System.out.println(map.get("读者A"));
System.out.println(map.containsKey("读者A"));
Set<String> set =map.keySet();
Iterator<String> it1 = set.iterator();
while(it1.hasNext()){
String str = it1.next();
System.out.println(map.get(str));
}
Set<Map.Entry<String,String >> set2 = map.entrySet();
Iterator<Map.Entry<String ,String >> it2 = set2.iterator();
while (it2.hasNext()){
Map.Entry<String ,String > entry = it2.next();
System.out.println(entry.getKey()+"="+entry.getValue());
}
}
}