Java——集合(Collection、List、Set、Map),开发必用!
今天是Java的学习进入了集合的学习。集合是Java开发中最常用的内容之一几乎天天都要用集合和数组类似都是容器但集合更强大可以存储任意数量的对象还可以自动扩容。下面是我的学习总结。一、集合概述1. 什么是集合集合是一种容器用于存储数量不等的多个对象。集合相关的接口和类位于java.util包中。2. 学习集合的四个角度集合接口的特点集合接口的功能方法集合接口对应的实现类集合的遍历方式3. 集合体系结构Collection接口 ├── List接口→ ArrayList、LinkedList、Vector └── Set接口 → HashSet、TreeSet、LinkedHashSet Map接口 ├── HashMap ├── Hashtable └── TreeMap二、Collection体系1. Collection接口父接口特点存储任意类型的Object对象。常用方法方法说明add(Object o)添加元素contains(Object o)是否包含某元素remove(Object o)删除元素size()获取元素个数三、List接口重点1. 特点存储任意类型的Object对象有序按添加顺序有下标从0开始元素允许重复2. 常用方法List list new ArrayList(); // 添加元素 list.add(A); // 尾部添加 list.add(1, B); // 指定下标插入 // 获取元素 Object o list.get(0); // 根据下标获取 // 删除元素 Object removed list.remove(1); // 删除指定下标元素 // 修改元素 Object old list.set(0, C); // 修改指定下标元素 // 获取长度 int size list.size();3. 实现类对比【面试重点】实现类底层查询效率增删效率线程安全ArrayList数组高低不安全JDK1.2Vector数组高低安全JDK1.0LinkedList链表低高不安全JDK1.2面试题ArrayList和LinkedList的区别ArrayList底层是数组查询快、增删慢LinkedList底层是链表增删快、查询慢。ArrayList扩容机制JDK1.7创建时不分配空间第一次add()时才分配初始容量10扩容倍率1.5倍4. List的三种遍历方式ListString list new ArrayList(); list.add(A); list.add(B); list.add(C); // 方式1下标遍历 for (int i 0; i list.size(); i) { System.out.println(list.get(i)); } // 方式2forEach遍历增强for【开发最常用】 for (String s : list) { System.out.println(s); } // 方式3迭代器遍历 IteratorString it list.iterator(); while (it.hasNext()) { String s it.next(); System.out.println(s); }四、泛型1. 为什么需要泛型没有泛型的集合什么类型都能放取出来需要强转容易出错。List list new ArrayList(); list.add(hello); list.add(123); // 混入其他类型 String s (String) list.get(0); // OK String s2 (String) list.get(1); // 运行报错2. 泛型集合使用泛型后集合只能存储指定类型更安全ListString list new ArrayListString(); list.add(hello); // list.add(123); // 编译报错 String s list.get(0); // 不需要强转注意泛型不能使用基本数据类型要用包装类java复制下载ListInteger list new ArrayList(); // ✅ Listint list new ArrayList(); // ❌ 报错五、Collections工具类Collections是操作集合的工具类提供了大量静态方法。常用方法ListInteger list new ArrayList(); list.add(3); list.add(1); list.add(4); list.add(2); // 倒置 Collections.reverse(list); // [2, 4, 1, 3] // 随机打乱 Collections.shuffle(list); // 每次结果不同 // 排序要求元素实现Comparable接口 Collections.sort(list); // [1, 2, 3, 4]自定义排序面试重点方式1实现Comparable接口内置比较器class Student implements ComparableStudent { private String name; private Integer age; Override public int compareTo(Student o) { // 返回正数this大于o // 返回负数this小于o // 返回0相等 return this.age - o.age; // 按年龄升序 } } // 使用 Collections.sort(list);方式2使用Comparator接口外置比较器Collections.sort(list, new ComparatorStudent() { Override public int compare(Student s1, Student s2) { return s1.getAge() - s2.getAge(); } });面试题Collection和Collections的区别CollectionCollections接口集合体系的父接口类操作集合的工具类List、Set是它的子接口提供sort、reverse等静态方法六、Set接口1. 特点存储任意类型对象无序不保证添加顺序无下标元素不允许重复2. 实现类HashSet重点保证元素不重复的原理调用对象的hashCode()计算存储位置如果该位置没有元素直接存储如果有元素调用equals()比较内容equals()返回true→ 拒绝添加重复equals()返回false→ 允许添加自定义对象存入HashSet必须重写hashCode()和equals()class Student { private String name; private Integer age; Override public int hashCode() { return name.hashCode() age.hashCode(); } Override public boolean equals(Object obj) { if (this obj) return true; if (obj null) return false; if (getClass() ! obj.getClass()) return false; Student s (Student) obj; return this.name.equals(s.name) this.age.equals(s.age); } }3. TreeSet排序TreeSet会对元素进行自动排序。自定义对象需要实现Comparable接口。SetStudent set new TreeSet(); // 元素按compareTo方法定义的规则排序4. LinkedHashSet是HashSet的子类按照添加顺序存储同时保证元素不重复七、Map接口重点1. 特点存储键值对Key-Value键无序、无下标、不允许重复值无序、无下标、允许重复2. 常用方法方法说明put(K key, V value)添加键值对键重复时覆盖旧值get(K key)根据键获取值remove(K key)根据键删除键值对containsKey(K key)是否包含某键containsValue(V value)是否包含某值size()键值对个数MapString, Integer map new HashMap(); // 添加 map.put(张三, 18); map.put(李四, 20); Integer old map.put(张三, 19); // 覆盖返回被覆盖的旧值18 // 获取 Integer age map.get(张三); // 19 // 删除 Integer removed map.remove(李四); // 返回20 // 判断 boolean hasKey map.containsKey(张三); // true boolean hasValue map.containsValue(19); // true3. 实现类对比【面试重点】实现类版本线程安全null键/值HashMapJDK1.2不安全允许HashtableJDK1.0安全不允许TreeMap-不安全键可排序LinkedHashMap-不安全按添加顺序面试题HashMap和Hashtable的区别HashMap线程不安全效率高Hashtable线程安全效率低HashMap允许null作为key和valueHashtable不允许4. Properties了解Properties是Hashtable的子类键和值都是String类型常用于读取配置文件。5. Map的三种遍历方式MapString, Integer map new HashMap(); map.put(A, 1); map.put(B, 2); // 方式1键遍历最常用 SetString keys map.keySet(); for (String key : keys) { Integer value map.get(key); System.out.println(key value); } // 方式2值遍历 CollectionInteger values map.values(); for (Integer value : values) { System.out.println(value); } // 方式3键值对遍历 SetMap.EntryString, Integer entries map.entrySet(); for (Map.EntryString, Integer entry : entries) { String key entry.getKey(); Integer value entry.getValue(); System.out.println(key value); }八、我踩过的坑坑1HashSet中自定义对象没有重写hashCode/equalsSetStudent set new HashSet(); set.add(new Student(张三, 18)); set.add(new Student(张三, 18)); // 能加进去解决重写hashCode()和equals()方法。坑2TreeSet中自定义对象没有实现ComparableSetStudent set new TreeSet(); // 运行报错ClassCastException解决让Student实现Comparable接口。坑3List遍历时删除元素for (String s : list) { if (s.equals(A)) { list.remove(s); // 可能报ConcurrentModificationException } }解决使用迭代器的remove()方法。坑4泛型忘记用包装类Listint list new ArrayList(); // 编译报错解决用Integer代替int。坑5Map中get方法返回nullInteger value map.get(不存在的键); // 返回null解决使用前先containsKey()判断。九、集合对比总结接口特点常用实现类适用场景List有序、有下标、可重复ArrayList查询多、增删少Set无序、无下标、不重复HashSet去重Map键值对、键不重复HashMap根据键查值十、小练习练习1统计字符串中每个字符出现的次数String str hello world; MapCharacter, Integer map new HashMap(); for (char c : str.toCharArray()) { if (map.containsKey(c)) { map.put(c, map.get(c) 1); } else { map.put(c, 1); } } System.out.println(map);练习2List去重ListInteger list Arrays.asList(1, 2, 3, 1, 2, 4); SetInteger set new HashSet(list); ListInteger result new ArrayList(set);总结今天学的内容是Java开发的必备技能一定要熟练掌握集合一句话总结ArrayList数组实现查询快开发最常用LinkedList链表实现增删快HashSet去重重写hashCodeequalsTreeSet自动排序实现ComparableHashMap键值对键不重复开发最常用面试高频题ArrayList和LinkedList的区别HashMap和Hashtable的区别Collection和Collections的区别HashSet去重的原理三种遍历方式的写法我接下来的任务把课堂上的集合案例都敲一遍包括自定义对象存储、排序、遍历等加上注释再做一些练习题巩固。如果你也在学Java欢迎一起交流我们明天继续