10.1集合类概述

为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),Java 提供了集合类。集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。Java 所有的集合类都位于 java.util 包下,提供了一个表示和操作对象集合的统一构架,包含大量集合接口,以及这些接口的实现类和操作它们的算法。

集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的引用变量),而集合里只能保存对象(实际上只是保存对象的引用变量,但通常习惯上认为集合里保存的是对象)。

Java 集合类型分为 Collection 和 Map,它们是 Java 集合的根接口,这两个接口又包含了一些子接口或实现类。。

 对于 Set、List、Queue 和 Map 这 4 种集合,Java 最常用的实现类分别是 HashSet、TreeSet、ArrayList、ArrayDueue、LinkedList 和 HashMap、TreeMap 等。表 2 介绍了集合中这些常用的实现类。

10.2Collection接口

Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。Collection 接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作。定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 合。

注意:以上方法完全来自于 Java API 文档,读者可自行参考 API 文档来查阅这些方法的详细信息。读者无需硬性记忆这些方法,可以和实际生活结合记忆。集合类就像容器,现实生活中容器的功能,就是添加对象、删除对象、清空容器和判断容器是否为空等,集合类为这些功能都提供了对应的方法。

public static void main(String[] args) {//主方法ArrayList list1 = new ArrayList(); // 创建集合 list1ArrayList list2 = new ArrayList(); // 创建集合 list2list1.add("one"); // 向 list1 添加一个元素list1.add("two"); // 向 list1 添加一个元素list2.addAll(list1); // 将 list1 的所有元素添加到 list2list2.add("three"); // 向 list2 添加一个元素System.out.println("list2 集合中的元素如下:");//输出内容Iterator it1 = list2.iterator();//创建迭代器while (it1.hasNext()) {//while循环输出所有元素System.out.print(it1.next() + "、");//输出语句}
}

运行结果:

public static void main(String[] args) {ArrayList list1 = new ArrayList(); // 创建集合 list1ArrayList list2 = new ArrayList(); // 创建集合 list2list1.add("one");list1.add("two");list1.add("three");System.out.println("list1 集合中的元素数量:" + list1.size()); // 输出list1中的元素数量list2.add("two");list2.add("four");list2.add("six");System.out.println("list2 集合中的元素数量:" + list2.size()); // 输出list2中的元素数量list2.remove(2); // 删除第 3 个元素System.out.println("\nremoveAll() 方法之后 list2 集合中的元素数量:" + list2.size());System.out.println("list2 集合中的元素如下:");Iterator it1 = list2.iterator();while (it1.hasNext()) {System.out.print(it1.next() + "、");}list1.removeAll(list2);System.out.println("\nremoveAll() 方法之后 list1 集合中的元素数量:" + list1.size());System.out.println("list1 集合中的元素如下:");Iterator it2 = list1.iterator();while (it2.hasNext()) {System.out.print(it2.next() + "、");

运行结果如下:

 注意:retainAll( ) 方法的作用与 removeAll( ) 方法相反,即保留两个集合中相同的元素,其他全部删除

10.3List集合

List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。

10.3.1List接口

10.3.2List接口的实现类

注意:当调用 List 的 set(int index, Object element) 方法来改变 List 集合指定索引处的元素时,指定的索引必须是 List 集合的有效索引。例如集合长度为 4,就不能指定替换索引为 4 处的元素,也就是说这个方法不会改变 List 集合的长度。

public class Test {public static void main(String[] args) {Product pd1 = new Product(4, "木糖醇", 10);Product pd2 = new Product(5, "洗发水", 12);Product pd3 = new Product(3, "热水壶", 49);List list = new ArrayList(); // 创建集合list.add(pd1);list.add(pd2);list.add(pd3);System.out.println("*************** 商品信息 ***************");for (int i = 0; i < list.size(); i++) {// 循环遍历集合,输出集合元素Product product = (Product) list.get(i);System.out.println(product);}

运行结果如下:

public static void main(String[] args) {List list = new ArrayList();list.add("One");list.add("|");list.add("Two");list.add("|");list.add("Three");list.add("|");list.add("Four");System.out.println("list 集合中的元素数量:" + list.size());System.out.println("list 集合中的元素如下:");Iterator it = list.iterator();while (it.hasNext()) {System.out.print(it.next() + "、");}System.out.println("\n在 list 集合中'丨'第一次出现的位置是:" + list.indexOf("|"));System.out.println("在 list 集合中'丨'最后一次出现的位置是:" + list.lastIndexOf("|"));
}

运行结果如下:

public static void main(String[] args) {List list = new ArrayList();list.add("One");list.add("Two");list.add("Three");list.add("Four");list.add("Five");list.add("Six");list.add("Seven");System.out.println("list 集合中的元素数量:" + list.size());System.out.println("list 集合中的元素如下:");Iterator it = list.iterator();while (it.hasNext()) {System.out.print(it.next() + "、");}List sublist = new ArrayList();sublist = list.subList(2, 5); // 从list集合中截取索引2~5的元素,保存到sublist集合中System.out.println("\nsublist 集合中元素数量:" + sublist.size());System.out.println("sublist 集合中的元素如下:");it = sublist.iterator();while (it.hasNext()) {System.out.print(it.next() + "、");}
}

运行结果如下:

10.3.3Iterator

public class Test {public static void main(String[] args) {LinkedList<String> products = new LinkedList<String>(); // 创建集合对象String p1 = new String("六角螺母");String p2 = new String("10A 电缆线");String p3 = new String("5M 卷尺");String p4 = new String("4CM 原木方板");products.add(p1); // 将 p1 对象添加到 LinkedList 集合中products.add(p2); // 将 p2 对象添加到 LinkedList 集合中products.add(p3); // 将 p3 对象添加到 LinkedList 集合中products.add(p4); // 将 p4 对象添加到 LinkedList 集合中String p5 = new String("标准文件夹小柜");products.addLast(p5); // 向集合的末尾添加p5对象System.out.print("*************** 商品信息 ***************");System.out.println("\n目前商品有:");for (int i = 0; i < products.size(); i++) {System.out.print(products.get(i) + "\t");}System.out.println("\n第一个商品的名称为:" + products.getFirst());System.out.println("最后一个商品的名称为:" + products.getLast());products.removeLast(); // 删除最后一个元素System.out.println("删除最后的元素,目前商品有:");for (int i = 0; i < products.size(); i++) {System.out.print(products.get(i) + "\t");}

运行结果如下:

10.4Set集合

Set 集合类似于一个罐子,程序可以依次把多个对象“丢进”Set 集合,而 Set 集合通常不能记住元素的添加顺序。也就是说 Set 集合中的对象不按特定的方式排序,只是简单地把对象加入集合。Set 集合中不能包含重复的对象,并且最多只允许包含一个 null 元素。

10.4.1Set接口

HashSet 具有以下特点:

不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
集合元素值可以是 null。

当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据该 hashCode 值决定该对象在 HashSet 中的存储位置。如果有两个元素通过 equals() 方法比较返回的结果为 true,但它们的 hashCode 不相等,HashSet 将会把它们存储在不同的位置,依然可以添加成功。

也就是说,两个对象的 hashCode 值相等且通过 equals() 方法比较返回结果为 true,则 HashSet 集合认为两个元素相等。

在 HashSet 类中实现了 Collection 接口中的所有方法。HashSet 类的常用构造方法重载形式如下。

HashSet():构造一个新的空的 Set 集合。
HashSet(Collection<? extends E>c):构造一个包含指定 Collection 集合元素的新 Set 集合。其中,“< >”中的 extends 表示 HashSet 的父类,即指明该 Set 集合中存放的集合元素类型。c 表示其中的元素将被存放在此 Set 集合中。

public static void main(String[] args) {HashSet<String> courseSet = new HashSet<String>(); // 创建一个空的 Set 集合String course1 = new String("Java入门教程");String course2 = new String("Python基础教程");String course3 = new String("C语言学习教程");String course4 = new String("Golang入门教程");courseSet.add(course1); // 将 course1 存储到 Set 集合中courseSet.add(course2); // 将 course2 存储到 Set 集合中courseSet.add(course3); // 将 course3 存储到 Set 集合中courseSet.add(course4); // 将 course4 存储到 Set 集合中System.out.println("C语言中文网教程有:");Iterator<String> it = courseSet.iterator();while (it.hasNext()) {System.out.println("《" + (String) it.next() + "》"); // 输出 Set 集合中的元素}System.out.println("有" + courseSet.size() + "套精彩教程!");
}

运行结果如下:

注意:在以上示例中,如果再向 CourseSet 集合中再添加一个名称为“Java入门教程”的 String 对象,则输出的结果与上述执行结果相同。也就是说,如果向 Set 集合中添加两个相同的元素,则后添加的会覆盖前面添加的元素,即在 Set 集合中不会出现相同的元素。

10.4.2Set接口的实现类

public class Test08 {public static void main(String[] args) {TreeSet<Double> scores = new TreeSet<Double>(); // 创建 TreeSet 集合Scanner input = new Scanner(System.in);System.out.println("------------学生成绩管理系统-------------");for (int i = 0; i < 5; i++) {System.out.println("第" + (i + 1) + "个学生成绩:");double score = input.nextDouble();// 将学生成绩转换为Double类型,添加到TreeSet集合中scores.add(Double.valueOf(score));}Iterator<Double> it = scores.iterator(); // 创建 Iterator 对象System.out.println("学生成绩从低到高的排序为:");while (it.hasNext()) {System.out.print(it.next() + "\t");}System.out.println("\n请输入要查询的成绩:");double searchScore = input.nextDouble();if (scores.contains(searchScore)) {System.out.println("成绩为: " + searchScore + " 的学生存在!");} else {System.out.println("成绩为: " + searchScore + " 的学生不存在!");}// 查询不及格的学生成绩SortedSet<Double> score1 = scores.headSet(60.0);System.out.println("\n不及格的成绩有:");for (int i = 0; i < score1.toArray().length; i++) {System.out.print(score1.toArray()[i] + "\t");}// 查询90分以上的学生成绩SortedSet<Double> score2 = scores.tailSet(90.0);System.out.println("\n90 分以上的成绩有:");for (int i = 0; i < score2.toArray().length; i++) {System.out.print(score2.toArray()[i] + "\t");}}
}

运行结果如下:                                                                                                                                                                              注意:在使用自然排序时只能向 TreeSet 集合中添加相同数据类型的对象,否则会抛出 ClassCastException 异常。如果向 TreeSet 集合中添加了一个 Double 类型的对象,则后面只能添加 Double 对象,不能再添加其他类型的对象,例如 String 对象等。

10.5Map集合

Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据。

Map 集合里保存着两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 的 key 不允许重复,value 可以重复,即同一个 Map 对象的任何两个 key 通过 equals 方法比较总是返回 false。

Map 中的 key 和 value 之间存在单向一对一关系,即通过指定的 key,总能找到唯一的、确定的 value。从 Map 中取出数据时,只要给出指定的 key,就可以取出对应的 value。

Map 接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。

10.5.1Map接口

Map 集合最典型的用法就是成对地添加、删除 key-value 对,接下来即可判断该 Map 中是否包含指定 key,也可以通过 Map 提供的 keySet() 方法获取所有 key 组成的集合,进而遍历 Map 中所有的 key-value 对。下面程序示范了 Map 的基本功能。

10.5.2Map接口的实现类

Map接口常用的实现类有HashMap和TreeMap两种,分别如下。
(1)HashMap类是基于哈希表的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键,但必须保证键的唯一性。HashMap通过哈希表对其内部的映射关系进行快速查找、此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
(2)TreeMap类不仅实现了Map接口,还实现了java、uili、SortedMap接口,因此,集合中的映射关系具有一定的顺序。但在添加、删除和定位映射关系时,TreeMap类比HashMap类性能稍差。由于TreeMap类实现的Map集合中的映射关系是根据键对象按照一定的顺序排列的,因此不允许键对象是null.

import java.util.*;public class UseHashMap {public static void main(String[] args) {Map<String, String> map = new HashMap<>(); // 创建Map实例map.put("ISBN-978654", "Java从入门到精通"); // 向集合中添加对象map.put("ISBN-978361", "Android从入门到精通");map.put("ISBN-978893", "21天学Android");map.put("ISBN-978756", "21天学Java");Set<String> set = map.keySet(); // 构建Map集合中所有key对象的集合Iterator<String> it = set.iterator(); // 创建集合迭代器System.out.println("key值:");while (it.hasNext()) { // 遍历集合System.out.print(it.next()+"\t");}Collection<String> coll = map.values(); // 构建Map集合中所有values值集合it = coll.iterator();System.out.println("\nvalues值:");while (it.hasNext()) { // 遍历集合System.out.print(it.next()+"\t");}}
}

运行结果如下:

public class Test09 {public static void main(String[] args) {HashMap users = new HashMap();users.put("11", "张浩太"); // 将学生信息键值对存储到Map中users.put("22", "刘思诚");users.put("33", "王强文");users.put("44", "李国量");users.put("55", "王路路");System.out.println("******** 学生列表 ********");Iterator it = users.keySet().iterator();while (it.hasNext()) {// 遍历 MapObject key = it.next();Object val = users.get(key);System.out.println("学号:" + key + ",姓名:" + val);}Scanner input = new Scanner(System.in);System.out.println("请输入要删除的学号:");int num = input.nextInt();if (users.containsKey(String.valueOf(num))) { // 判断是否包含指定键users.remove(String.valueOf(num)); // 如果包含就删除} else {System.out.println("该学生不存在!");}System.out.println("******** 学生列表 ********");it = users.keySet().iterator();while (it.hasNext()) {Object key = it.next();Object val = users.get(key);System.out.println("学号:" + key + ",姓名:" + val);}}
}

运行结果如下:

TreeMap 类的使用方法与 HashMap 类相同,唯一不同的是 TreeMap 类可以对键对象进行排序。

10.6集合的使用场合

Map 集合的遍历与 List 和 Set 集合不同。Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。Map 以及实现 Map 的接口类(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下几种方式遍历。
1)在 for 循环中使用 entries 实现 Map 的遍历(最常见和最常用的)。

public static void main(String[] args) {Map<String, String> map = new HashMap<String, String>();map.put("Java入门教程", "http://c.biancheng.net/java/");map.put("C语言入门教程", "http://c.biancheng.net/c/");for (Map.Entry<String, String> entry : map.entrySet()) {String mapKey = entry.getKey();String mapValue = entry.getValue();System.out.println(mapKey + ":" + mapValue);}
}

2)使用 for-each 循环遍历 key 或者 values,一般适用于只需要 Map 中的 key 或者 value 时使用。性能上比 entrySet 较好。

Map<String, String> map = new HashMap<String, String>();
map.put("Java入门教程", "http://c.biancheng.net/java/");
map.put("C语言入门教程", "http://c.biancheng.net/c/");
// 打印键集合
for (String key : map.keySet()) {System.out.println(key);
}
// 打印值集合
for (String value : map.values()) {System.out.println(value);
}

3)使用迭代器(Iterator)遍历

Map<String, String> map = new HashMap<String, String>();
map.put("Java入门教程", "http://c.biancheng.net/java/");
map.put("C语言入门教程", "http://c.biancheng.net/c/");
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {Entry<String, String> entry = entries.next();String key = entry.getKey();String value = entry.getValue();System.out.println(key + ":" + value);
}

4)通过键找值遍历,这种方式的效率比较低,因为本身从键取值是耗时的操作。

for(String key : map.keySet()){String value = map.get(key);System.out.println(key+":"+value);
}

前面介绍了Java中最常见的3种集合:List集合、Set集合和Map集合,那么在实际开发中,具体何时应该选择哪种集合呢?这里我们总结了以下原则。
(1) List集合关注的是索引,其元素是顺序存放的,例如一个班的学生成绩,成绩可以重复,就可以使用List集合存取,
(2) Set集合关注唯一性,它的值不允许重复,例如每个班的学生的学号,每个学生的学号是不能重复的.
(3) Map集合关注的是唯一的标识符(KEY),它将唯一的键映射到某个元素,例如每个班学生的学号与姓名的映射,每个学号对应一个学生的姓名,学号是不能重复的,但是学生的姓名有可能重复。

第十章 集合类 总结相关推荐

  1. JAVA SE基础笔记

    第一天  JDK安装.快捷键.JAVA语言特点 1.Java语言的概述 1.1 Java语言的背景 Java语言诞生于1995年,在编程语言排行榜占据重要的地位. Java语言之父是高斯林,以前隶属于 ...

  2. Java第十章总结集合类

    10.1集合类概述 为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),Java 提供了集合类.集合类主要负责保存.盛装其他数据,因此集合类也被称为容器类.Java 所有的集合类 ...

  3. 【哈工大软件构造】学习笔记10 第十章、第十一章、第十二章

    目录 第十章 面向可维护性的构造技术 1 软件维护和演化 2 可维护性的度量 3 模块化设计和模块性准则 模块划分的五个准则 模块设计的五个原则 耦合度和聚合度 4 OO设计准则:SOLID SRP ...

  4. Java 第十章.泛型

    Java 第十章.泛型 1.为什么要有泛型 2.在集合中使用泛型 3.自定义泛型结构 3.1使用 3.2注意点 3.3泛型方法 3.4泛型方法的使用情景 4.泛型在继承上的体现 5.通配符的使用 5. ...

  5. java常用的集合对象_java常用实体类、集合类

    java常用实体类.集合类 [转自51cto博客jichangwei的BLOG] 1:String类,字符串是常量,他们的值在创建之后不能更改,可以共享. equals()用来比较两个字符串的值,== ...

  6. 获取后台集合并遍历_java集合类汇总,终于出总结了,再也不用担心混淆了

    一:集合与数组 数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用. 集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用. ...

  7. 数字图像处理——第十章 图像分割

    数字图像处理--第十章 图像分割 文章目录 数字图像处理--第十章 图像分割 写在前面 1 点.线和边缘检测 1.1 孤立点的检测 1.2 线检测 1.3 边缘检测 2 阈值处理 2.1 单一全局阈值 ...

  8. C#的6种常用集合类大比拼【月儿原创】

    C#的6种常用集合类大比拼 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/           时间:2007.6.27 说明:MSDN没有说出几种集合类其间的区别 ...

  9. 通过C#实现集合类纵览.NET Collections及相关技术

    概述:在真正的对象化开发项目中,我们通常会将常用的业务实体抽象为特定的类,如Employee.Customer.Contact等,而多数的类之间会存在着相应的关联或依存关系,如Employee和Cus ...

最新文章

  1. $_SERVER['SCRIPT_FILENAME'] 与 __FILE__ 区别
  2. 中国鱼胶原蛋白行业应用前景与十四五投资建议报告2022年
  3. 重写StyleSheetTheme
  4. Lomsat gelral
  5. 新疆大学OJ(ACM) 1099: 数列有序!
  6. HttpModule HttpHandler(转)
  7. Hibernate与mybatis比较
  8. android gsm编程,Android新手入门 FAQ
  9. Altium Designer 17 安装方法及步骤
  10. 安卓机型app的编译与反编译 apk文件的简单说明与解析
  11. 【数值计算】计算机中的数值计算
  12. 短期出差北京个人所见所闻所感
  13. 输入 10 个学生 3 门课的成绩,用函数实现:找出最高的分数所对应的学号和成绩
  14. 华为MateBook E 12.6英寸 win11 16g+512g 轻评测
  15. STM32-SWD仿真时PB3,PB4,PA15使用问题
  16. idea 上传项目到码云git仓库提交到gitee(完整操作流程)
  17. 基于html篮球网页游戏,分享一款在线打篮球游戏网页源码
  18. vue 首页白屏优化
  19. 萨克斯的最佳清洁办法
  20. Hyper-V虚拟机启动出现黑屏光标闪动

热门文章

  1. 计算机是如何做加法的?(7)——回顾与总结
  2. linux怎么烧写文件系统,烧写LINUX最小文件系统
  3. openstack安装和使用
  4. 许亲亲--1101210998 第三次作业
  5. 建立自己的手写笔画图案
  6. python web开发屠龙刀flask
  7. ART运行时垃圾收集(GC)过程分析
  8. 2021-05-08 小华子第一篇
  9. 今天,传说中的老方给我们班上课了
  10. 图像处理入门100题(三)