集合框架
- 一、 集合框架的概述
- 二、Collection中的方法的使用
- 2.1 ``add()``:向集合中添加元素
- 2.2 ``size()``:获取添加的元素的个数
- 2.3 ``addAll()``:将另外一个集合的元素加入到当前集合里
- 2.4 ``isEmpty``:判断当前集合是否为空
- 2.5 ``contains(Object obj)``:判断当前集合中是否包含obj
- 2.6 ``containsAll(Collection coll1)``:判断当前集合中是否包含coll1中的所有元素
- 2.7 ``remove(Object obj)``:从当前集合中移除 obj对象,移除成功返回==true==,移除失败返回==false==。
- 2.8 ``removeAll(Collection coll1)``:从集合中移除所有 coll1 中有的元素移除移除成功返回==true==,移除失败返回==false==。
- 2.9 ``retrainAll(Collection coll)``:交集:获取当前集合和coll的交集,并返回给当前集合
- 2.10 ``equals(Object obj)``:当前集合与形参集合的元素相同且顺序相同,才能返回true
- 2.11 ``hashCode()``:返回当前对象的哈希值
- 2.12``toArray()``:集合转数组
- 2.13 ``iterator()``:返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中
- 2.14 for- each
- 三、 Collection子接口之一:List接口
- 四、 Collection子接口之二:Set接口
一、 集合框架的概述
- 集合、数组都是对多个数据解析存储操作的结构,简称Java容器
说明:此时的存储主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.doc,数据库中)- 数组在存储多个数据方面的特点:
①:一旦初始化之后,长度就确定了
②:数组一旦定义好,数组的元素类型就确定了,就只能操作指定类型的数据- 数组在存储多个数据方面的缺点
①:数组一旦长度确定,就不可修改,不便于开发
②:数组中日光的方法非常有限,对数据执行操作(添加,删除,插入)时,非常不便,同时效率不高
③:获取数组中实际元素的个数的需求,数组没有实现现成的属性或方法可用
④:数组存储数据的特点:有序、可重复。对于无序、不可重复的需求、不能满足
1.1 Java集合可分为 Collection 和 Map 两种体系
Collection接口
:单列数据,定义了存取一组对象的方法集合List
:元素有序、可重复的集合---->动态数组Set
:元素无需、不可重复的集合
*Map接口
:双列数据,保存具有映射关系"key-value"的集合
1.1.1 Collection接口继承树 & Map接口继承树
- Collection接口继承树
- Map 接口继承树
二、Collection中的方法的使用
2.1 add()
:向集合中添加元素
Collection collection = new ArrayList();
collection.add("AA");
collection.add("CC");
collection.add(12);//自动装箱
collection.add(new Date());
2.2 size()
:获取添加的元素的个数
System.out.println(collection.size());
输出:
4
2.3 addAll()
:将另外一个集合的元素加入到当前集合里
Collection collection1 = new ArrayList();
collection1.add("FIX");
collection1.add(new Object());
collection1.add(432);
collection.addAll(collection1);
System.out.println(collection.size());
System.out.println(collection);
输出
7
[AA, CC, 12, Sun Sep 05 15:36:05 CST 2021, FIX, java.lang.Object@621be5d1, 432]
2.4 isEmpty
:判断当前集合是否为空
System.out.println(collection.isEmpty());
collection.clear();//清空当前集合里的元素
System.out.println(collection.isEmpty());
输出
false
true
2.5 contains(Object obj)
:判断当前集合中是否包含obj
Collection collection1 = new ArrayList();
collection1.add("FIX");
collection1.add(new String("Tom"));
collection1.add(432);
collection1.add(new Person("Tom",12));
System.out.println(collection1.contains(new String("Tom")));//true
System.out.println(collection1.contains(new Person("Tom", 12)));//false
collection1.contains(new String("Tom"))
:为true,因为此处调用的是equals,String已经重写过equals类,自定义类此处没有重写,所以相当于使用的 " == "来判断。所以此处需要我们自己重写toString方法
//重写equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
重写之后contains的输出
System.out.println(collection1.contains(new Person("Tom", 12)));//false,
//重写Person类的equals方法后输出:true
true
我们在判断时会调用obj对象所在类的equals(),故:向Collection接口实现类的对象中添加数据obj时,要求obj所在类要重写equals()方法
2.6 containsAll(Collection coll1)
:判断当前集合中是否包含coll1中的所有元素
Collection coll1 = Arrays.asList(123,432);
System.out.println(collection1.containsAll(coll1));//false
Collection cool2 = Arrays.asList("FIX",432,new Person("Tom",12));
System.out.println(collection1.containsAll(cool2));//true
输出
false
true
2.7 remove(Object obj)
:从当前集合中移除 obj对象,移除成功返回true,移除失败返回false。
System.out.println(collection1);
System.out.println(collection1.remove(456));//false
System.out.println(collection1);
System.out.println(collection1.remove(new Person("Tom", 12)));//true
System.out.println(collection1);
输出:
[FIX, Tom, 432, test.Person@4ee285c6]
false
[FIX, Tom, 432, test.Person@4ee285c6]
true
[FIX, Tom, 432]
2.8 removeAll(Collection coll1)
:从集合中移除所有 coll1 中有的元素移除移除成功返回true,移除失败返回false。
//removeAll()
System.out.println("10"+collection1);
Collection coll3 =Arrays.asList("SYS",80);
System.out.println("11"+collection1.removeAll(coll3));//false
System.out.println("12"+collection1);
Collection coll4 =Arrays.asList("SYS",432);
System.out.println("13"+collection1.removeAll(coll4));//true
System.out.println("14"+collection1);//
Collection coll5 =Arrays.asList("FIX",new String("Tom"),159);
System.out.println("15"+collection1.removeAll(coll5));//true
System.out.println("16"+collection1);
输出:
10[FIX, Tom, 432]
11false
12[FIX, Tom, 432]
13true
14[FIX, Tom]
15true
16[]
只要移除成功了一个元素,结果都会返回true
,只有当一个元素都没有移除时返回false
2.9 retrainAll(Collection coll)
:交集:获取当前集合和coll的交集,并返回给当前集合
public void test2(){
//retainAll
Collection collection1 = new ArrayList();
//add()
collection1.add("FIX");
collection1.add(new String("Tom"));
collection1.add(432);
collection1.add(new Person("Jerry",12));
Collection coll = Arrays.asList(432,"FIX",21);
Collection coll1 = Arrays.asList(21,"JPM");
System.out.println(collection1.retainAll(coll));
System.out.println(collection1);
System.out.println(collection1.retainAll(coll1));
System.out.println(collection1);
}
输出:
true
[FIX, 432]
true
[]
2.10 equals(Object obj)
:当前集合与形参集合的元素相同且顺序相同,才能返回true
@Test
public void test3(){
//retainAll
Collection collection1 = new ArrayList();
//add()
collection1.add("FIX");
collection1.add(new String("Tom"));
collection1.add(432);
collection1.add(new Person("Jerry",12));
Collection coll = Arrays.asList("FIX",new String("Tom"),432,new Person("Jerry",12));
Collection coll1 = Arrays.asList(new String("Tom"),432,new Person("Jerry",12),"FIX");
//完全相同
System.out.println(collection1.equals(coll));
//元素相同,顺序不同
System.out.println(collection1.equals(coll1));
}
输出:
true
false
2.11 hashCode()
:返回当前对象的哈希值
public void test4(){
//retainAll
Collection collection1 = new ArrayList();
collection1.add(432);
collection1.add("FIX");
collection1.add(false);
collection1.add(new String("Tom"));
collection1.add(new Person("Jerry",12));
//hashCode():
System.out.println(collection1.hashCode());
}
输出:
-466028381
Process finished with exit code 0
2.12toArray()
:集合转数组
public void test4(){
//retainAll
Collection collection1 = new ArrayList();
collection1.add(432);
collection1.add("FIX");
collection1.add(false);
collection1.add(new String("Tom"));
collection1.add(new Person("Jerry",12));
//toArray()
Object[] obj = collection1.toArray();
System.out.println(obj);
for (int i = 0 ; i < obj.length;i++){
System.out.println(obj[i]);
}
}
输出:
[Ljava.lang.Object;@621be5d1
432
FIX
false
Tom
Person{name='Jerry', age=12}
2.13 iterator()
:返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中
内部方法:hashNext()
:判断是否还有下一个元素、next
:指针下移,将下移以后位置上的元素返回。
@Test
public void test(){
Collection collection1 = new ArrayList();
collection1.add(432);
collection1.add("FIX");
collection1.add(false);
collection1.add(new String("Tom"));
collection1.add(new Person("Jerry",12));
Iterator iterator = collection1.iterator();
//方式一:不推荐
// for (int i = 0 ; i < collection1.size() ; i++){
// System.out.println(iterator.next());
// }
//方式二:推荐
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前
2.14 for- each
for- each
:增强for循环
内部仍然调用了迭代器
for (Object obj:collection1){
System.out.println(obj);
}
输出
432
FIX
false
Tom
Person{name='Jerry', age=12}
三、 Collection子接口之一:List接口
3.1 List接口概述
- 元素有序,且可重复
- List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素
3.2 List接口常用实现类
List接口:存储有序的、可重复的数据。 —>”动态数组“,替换原有的数组
3.2.1 三种常用实现类的对比
- 异:
ArrayList:作为List的主要实现类:线程不安全,效率高:底层使用Object[] elementData存储
LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList效率高:底层使用双向链表存储
Vector:List接口的古老实现类:线程安全,效率低:底层使用Object[] elementData存储
- 同:三个类都实现了List接口:存储有序的、可重复的数据
3.2.2 List遍历及方法总结
常用方法:
- 增:
add(Object obj))
- 删:
remove(int index) / temove(Object obj)
- 改:
set(int index,Object ele)
- 查:
get(int index)
- 插:
add(int index ,Object ele)
- 长度:
size()
- 遍历:①Iterator迭代器方式②增强for循环③普通循环
遍历
public void test2(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("DF");
list.add(new Person("Tom",12));
list.add(567);
//遍历方式一:迭代器方式
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//遍历方式二:增强for循环
for (Object obj:list){
System.out.println(obj);
}
//方式三:普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
四、 Collection子接口之二:Set接口
-
Set接口
:存储无序的、不可重复的数据(以HashSet说明)
无序性:不等于随机性。存储的数在底层数组中并非按照数组的索引顺序添加,根据数据的哈希值决定的
不可重复性:保证添加的元素按照equals方法判断时,不能返回true,即相同的元素只能添加一个
- Set中没有额外定义新的方法,使用的都是Collection中声明过的方法
- 要求:向Set中添加的数据,其所在类一定要重写hashCode()方法,和equals()方法
- 要求:重写的方法尽可能保持一致性:相等的对象必须具有相等的哈希值(散列值)
4.1 Set接口实现类——HashSet
作为Set接口的主要是实现类——线程不安全,利用存储null值
4.1.1 向HashSet添加元素
向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法,计算出次此元素在HashSet底层数组中存放的位置(即为:索引位置),判断数组此位置上是否已经有元素,如果此位置没有元素,则元素a添加成功;如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较a与b的哈希值,如果哈希值不同,则添加成功,如果哈希值不同,进而需要调用元素a所在类的equals()方法,equals返回true,添加失败,返回false则元素a添加成功。
HashSet底层是数组+链表的形结构储的
4.2 Set接口实现类——LinkedHashSet
HashSet的子类,遍历其内部数据时可以按照添加的顺序遍历
再添加数时,每个数据还维护了两个引用,记录此数据的前一个数据和后一个数据
对于频繁的遍历操作,LinkedHashSet效率高于HashSet
4.3 Set接口实现类——TreeSet
底层使用二叉树,可以按照添加对象的指定属性进行排序
向TreeSet中添加的数据,要求是相同类的对象
两种排序方式——自然排序、定制排序自然排序
实现Comparable接口
:自然排序中比较两个对象是否相同的标准:comoareTo(),返回0,不再是equals()定制排序
实现Comparator接口
:自然排序中比较两个对象是否相同的标准:comoare(),返回0,不再是equals()