写在前面
Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正!谢谢大家!!!
如果小哥哥小姐姐们对我的文章感兴趣,请不要吝啬你们的小手,多多点赞加关注呀!❤❤❤ 爱你们!!!
目录
【往期回顾】
一文带你深入理解【Java基础】· 常用类(上)字符串相关类
1. Java集合框架概述
1.1 为什么要使用集合
- 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用Array存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容器中。
数组在内存存储方面的特点:
- 数组初始化以后,长度就确定了。
- 数组声明的类型,就决定了进行元素初始化时的类型
数组在存储数据方面的弊端:
- 数组初始化以后,长度就不可变了,不便于扩展
- 数组中提供的属性和方法少,不便于进行添加、删除、插入等操作,且效率不高。同时无法直接获取存储元素的个数
- 数组存储的数据是有序的、可以重复的。---->存储数据的特点单一
- Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。
Java 集合可分为 Collection 和 Map 两种体系
- Collection接口:单列数据,定义了存取一组对象的方法的集合
- List:元素有序、可重复的集合
- Set:元素无序、不可重复的集合
- Map接口:双列数据,保存具有映射关系“key-value对”的集合
1.2 Collection接口继承树
2. Collection接口方法
2.1 Collection 接口
- Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
- JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。
- 在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。
2.2 Collection 接口方法
添加
- add(Object obj)
- addAll(Collection coll)
获取有效元素的个数
- int size()
清空集合
- void clear()
是否是空集合
- boolean isEmpty()
是否包含某个元素
- boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象
- boolean containsAll(Collection c):也是调用元素的equals方法来比较的。拿两个集合的元素挨个比较。
删除
- boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
- boolean removeAll(Collection coll):取当前集合的差集
取两个集合的交集
- boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
集合是否相等
- boolean equals(Object obj)
转成对象数组
- Object[] toArray()
获取集合对象的哈希值
- hashCode()
遍历
- iterator():返回迭代器对象,用于集合遍历
2.3 集合概述代码演示
import org.junit.Test; import java.util.ArrayList; import java.util.Collection; import java.util.Date; /** * 一、集合框架的概述 * * 1.集合、数组都是对多个数据进行存储操作的结构,简称Java容器。 * 说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中) * * 2.1 数组在存储多个数据方面的特点: * > 一旦初始化以后,其长度就确定了。 * > 数组一旦定义好,其元素的类型也就确定了。我们也就只能操作指定类型的数据了。 * 比如:String[] arr;int[] arr1;Object[] arr2; * 2.2 数组在存储多个数据方面的缺点: * > 一旦初始化以后,其长度就不可修改。 * > 数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高。 * > 获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用 * > 数组存储数据的特点:有序、可重复。对于无序、不可重复的需求,不能满足。 * * 二、集合框架 * |----Collection接口:单列集合,用来存储一个一个的对象 * |----List接口:存储有序的、可重复的数据。 -->“动态”数组 * |----ArrayList、LinkedList、Vector * * |----Set接口:存储无序的、不可重复的数据 -->高中讲的“集合” * |----HashSet、LinkedHashSet、TreeSet * * |----Map接口:双列集合,用来存储一对(key - value)一对的数据 -->高中函数:y = f(x) * |----HashMap、LinkedHashMap、TreeMap、Hashtable、Properties * * 三、Collection接口中的方法的使用 * */ public class CollectionTest { @Test public void test1() { Collection coll = new ArrayList(); //add(Object e):将元素e添加到集合coll中 coll.add("AA"); coll.add("BB"); coll.add(123);//自动装箱 coll.add(new Date()); //size():获取添加的元素的个数 System.out.println(coll.size());//4 //addAll(Collection coll1):将coll1集合中的元素添加到当前的集合中 Collection coll1 = new ArrayList(); coll1.add(456); coll1.add("CC"); coll.addAll(coll1); System.out.println(coll.size());//6 System.out.println(coll);//[AA, BB, 123, Sat Nov 26 22:20:22 CST 2022, 456, CC] //clear():清空集合元素 coll.clear(); //isEmpty():判断当前集合是否为空 System.out.println(coll.isEmpty());//true } }
import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** * Collection接口中声明的方法的测试 * * 结论: * 向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals(). */ public class CollectionTest { @Test public void test1() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); // Person p = new Person("Jerry",20); // coll.add(p); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); // 1.contains(Object obj):判断当前集合中是否包含obj // 我们在判断时会调用obj对象所在类的equals()。 boolean contains = coll.contains(123); System.out.println(contains);//true System.out.println(coll.contains(new String("Tom")));//true // System.out.println(coll.contains(p));//true System.out.println(coll.contains(new Person("Jerry", 20))); // Person equals().... // Person equals().... // Person equals().... // true // Person类重写的equals方法 // 2.containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中。 Collection coll1 = Arrays.asList(123, 4567); System.out.println(coll.containsAll(coll1));//false } @Test public void test2() { // 3.remove(Object obj):从当前集合中移除obj元素。 Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); coll.remove(1234); System.out.println(coll);// [123, 456, Person{name='Jerry', age=20}, Tom, false] coll.remove(new Person("Jerry", 20)); System.out.println(coll); // Person equals().... // Person equals().... // Person equals().... // [123, 456, Tom, false] // 4. removeAll(Collection coll1):差集:从当前集合中移除coll1中所有的元素。 Collection coll1 = Arrays.asList(123, 456); coll.removeAll(coll1); System.out.println(coll);// [Tom, false] } @Test public void test3() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); // 5.retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合 Collection coll1 = Arrays.asList(123,456,789); coll.retainAll(coll1); System.out.println(coll); // Person equals().... // Person equals().... // Person equals().... // [123, 456] //6.equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同。 Collection coll2 = new ArrayList(); coll2.add(456); coll2.add(123); coll2.add(new Person("Jerry", 20)); coll2.add(new String("Tom")); coll2.add(false); System.out.println(coll.equals(coll2));// false } @Test public void test4() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); // 7.hashCode():返回当前对象的哈希值 System.out.println(coll.hashCode());// -1200490100 // 8.集合 --->数组:toArray() Object[] arr = coll.toArray(); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } // 123 // 456 // Person{name='Jerry', age=20} // Tom // false // 拓展:数组 --->集合:调用Arrays类的静态方法asList() List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"}); System.out.println(list);// [AA, BB, CC] List arr1 = Arrays.asList(new int[]{123, 456}); System.out.println(arr1.size());//1 List arr2 = Arrays.asList(new Integer[]{123, 456}); System.out.println(arr2.size());//2 // 9.iterator():返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中测试 } }
import java.util.Objects; public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { System.out.println("Person equals()...."); 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); } @Override public int hashCode() { return Objects.hash(name, age); } }
3. Iterator迭代器接口
3.1 使用 Iterator 接口遍历集合元素
- Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
- GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。类似于“公交车上的售票员”、“火车上的乘务员”、“空姐”。
- Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。
- Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。
- 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
3.2 Iterator接口的方法
- 在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。
3.3 Iterator接口remove()方法
Iterator iter = coll.iterator();//回到起点 while(iter.hasNext()) { Object obj = iter.next(); if(obj.equals("Tom")) { iter.remove(); } }
注意:
- Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
- 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException。
3.4 使用 foreach 循环遍历集合元素
- Java 5.0 提供了 foreach 循环迭代访问 Collection和数组。
- 遍历操作不需获取Collection或数组的长度,无需使用索引访问元素。
- 遍历集合的底层调用Iterator完成操作。
- foreach还可以用来遍历数组。
3.5 Iterator代码演示
import org.junit.Test; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * 集合元素的遍历操作,使用迭代器Iterator接口 * 1.内部的方法:hasNext() 和 next() * 2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象, * 默认游标都在集合的第一个元素之前。 * 3.内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove() */ public class IteratorTest { @Test public void test1() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); Iterator iterator = coll.iterator(); //方式一: // System.out.println(iterator.next()); // System.out.println(iterator.next()); // System.out.println(iterator.next()); // System.out.println(iterator.next()); // System.out.println(iterator.next()); // //报异常:NoSuchElementException // System.out.println(iterator.next()); //方式二:不推荐 // for(int i = 0;i < coll.size();i++){ // System.out.println(iterator.next()); // } //方式三:推荐 hasNext():判断是否还有下一个元素 while (iterator.hasNext()) { //next():①指针下移 ②将下移以后集合位置上的元素返回 System.out.println(iterator.next()); } } @Test public void test2() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); //错误方式一:一次循环调用两次next,指针下移了两次 // Iterator iterator = coll.iterator(); // while((iterator.next()) != null){ // System.out.println(iterator.next()); // } //错误方式二: //集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。 while (coll.iterator().hasNext()) { System.out.print(coll.iterator().next());//123123123123...... } } //测试Iterator中的remove() //如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法, // 再调用remove都会报IllegalStateException。 @Test public void test3() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); //删除集合中"Tom" Iterator iterator = coll.iterator(); while (iterator.hasNext()) { // iterator.remove(); Object obj = iterator.next(); if ("Tom".equals(obj)) { iterator.remove(); } } //遍历集合 iterator = coll.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
3.6 foreach循环代码演示
import org.junit.Test; import java.util.ArrayList; import java.util.Collection; /** * jdk 5.0 新增了foreach循环,用于遍历集合、数组 */ public class ForTest { @Test public void test1() { Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry", 20)); coll.add(new String("Tom")); coll.add(false); //for(集合元素的类型 局部变量 : 集合对象) //内部仍然调用了迭代器。 for (Object obj : coll) { System.out.println(obj); } } @Test public void test2() { int[] arr = new int[]{1, 2, 3, 4, 5, 6}; //for(数组元素的类型 局部变量 : 数组对象) for (int i : arr) { System.out.println(i); } } //练习题 @Test public void test3() { String[] arr = new String[]{"MM", "MM", "MM"}; // //方式一:普通for赋值 // for(int i = 0;i < arr.length;i++){ // arr[i] = "GG"; // } //方式二:增强for循环 for (String s : arr) { s = "GG"; } for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]);//MM } } }
结语
本人会持续更新文章的哦!希望大家一键三连,你们的鼓励就是作者不断更新的动力