Java知识点04——集合(Set、List、Queue、Map、Collection、Iterator、Collections工具类)

  • 一、集合
    • 1.1 集合概述
  • 二、Collection
    • 2.1 介绍
    • 2.2 操作集合
    • 2.3 操作案例
  • 三、Set 集合
    • 3.1 介绍
    • 3.2 HashSet
      • 3.2.1 特点
      • 3.2.2 操作案例(重写hashCode和equals方法)
    • 3.3 LinkedHashSet
    • 3.4 TreeSet
      • 3.4.1 自然排序
      • 3.4.2 定制排序(重点)
  • 四、List 集合
    • 4.1 介绍
    • 4.2 ArrayList
    • 4.3 LinkedList
  • 五、Queue 集合
  • 六、Map 集合
    • 6.1 常用函数
    • 6.2 HashMap
    • 6.3 LinkedHashMap
    • 6.4 Entry(内部类)
  • 七、Iterator 接口(迭代器)
    • 7.1 介绍
    • 7.2 常用方法
    • 7.3 增强for(forEach)
      • 7.3.1 遍历数组
      • 7.3.2 遍历集合
  • 八、Collections 工具类
    • 8.1 排序
    • 8.2 查找、替换
    • 8.3 Comparable 接口
      • 8.3.1 单条件 排序
      • 8.3.2 多条件 排序
    • 8.4 Comparator 接口
  • 九、遍历集合的四种方式
    • 9.1 方式一:Lambda 表达式遍历集合
    • 9.2 方式二:Iterator 遍历集合
    • 9.3 方式三:Lambda 表达式遍历 Iterator
    • 9.4 方式四:foreach 循环遍历集合

声明:

  1. 该资料来自自己整理。
  2. 参考书籍 疯狂 Java讲义(第五版) 李刚©著

一、集合

1.1 集合概述

概念:对象的容器,定义了对多个对象进项操作的的常用方法。可实现数组的功能。

  • 集合和数组区别?

    (1)数组的长度是固定的。集合的长度是可变的。
    (2)数组可以存储基本类型和引用类型,集合只能存储引用类型。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

  • 位置: java.util.*;

如果访问List集合中的元素,可以直接根据元素的索引来访问;
如果访问Map集合中的元素,可以根据每项元素的key来访问其value;
如果访问Set集合中的元素,则只能根据元素本身来访问(这也是Set集合里元素不允许重复的原因);

集合本身是一个工具,它存放在java.util包中。在Collection接口定义着单列集合框架中最最共性的内容。

二、Collection

2.1 介绍


Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

  • boolean add(Object o): 用于向集合里添加一个元素。如果集合对象被添加操作改变了,则返回true。(把给定的对象添加到当前集合中 。)
  • boolean addAll(Collection c):用于把集合 c 里面的所有元素添加到指定集合里。如果集合对象被添加操作改变了,则返回true。
  • void clear() :清空集合中所有的元素,将集合长度变为0。
  • boolean remove(Object o): 把指定的元素从当前集合中删除,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法返回true。
  • boolean removeAll(Collection c): 从集合中删除集合 c 里包含的所有元素(相当于调用该方法的集合减集合 c ),如果删除了一个或一个以上的元素,该方法返回true。
  • boolean retainAll(Collection c):从集合中删除集合 c 里不包括的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回true。
  • boolean contains(Object o): 判断当前集合中是否包含指定元素。
  • boolean containsAll(Collection c):判断集合里是否包含集合 c 里的所有元素。
  • boolean isEmpty(): 判断当前集合是否为空。当前集合长度为 0 时返回true,否则返回false。
  • int size(): 返回集合中元素的个数。
  • Object[] toArray(): 把集合中的元素,存储到数组中,所有的集合元素变成对应的数组元素。

2.2 操作集合



2.3 操作案例

public class CollectionTest {public static void main(String[] args) {Collection c = new ArrayList();//添加元素c.add("孙悟空");c.add(6);//虽然集合里不能放基本类型的值,但Java支持自动装箱c.add(true);//输出集合cSystem.out.println(c);//[孙悟空, 6, true] //按存储时的顺序读取//遍历c集合for (Object o : c) {System.out.print(o+",");//孙悟空,6,true,}System.out.println();//删除指定元素c.remove(true);System.out.println("c集合的元素个数:"+c.size());//c集合的元素个数:2//判断集合c中是否包含指定字符串(元素)System.out.println("c集合中是否包含\"孙悟空\"字符串:"+c.contains("孙悟空"));//true//c集合转换成Object数组Object[] objects = c.toArray();System.out.println(objects);//[Ljava.lang.Object;@6d6f6e28System.out.println(c);//[孙悟空, 6]//forEach遍历objects数组for (Object o:objects) {System.out.print(o+",");//孙悟空,6,}System.out.println();//for遍历数组objectsfor (int i = 0; i < objects.length; i++) {System.out.print(objects[i]+",");//孙悟空,6,}System.out.println();Collection books = new HashSet();//向Set集合中添加元素books.add("Java讲义");books.add("php进阶教程");books.add("孙悟空");System.out.println(books);//[php进阶教程, 孙悟空, Java讲义] // 随机读取for (Object bo:books ) {System.out.print(bo+",");//php进阶教程,孙悟空,Java讲义, // 随机遍历}System.out.println();System.out.println("c集合是否包含\"孙悟空\"元素:"+books.contains("孙悟空"));//c集合是否包含"孙悟空"元素:trueSystem.out.println("c集合中是否完全包含books集合?"+c.containsAll(books));//c集合中是否完全包含books集合?false//用 c 集合减去books集合里的元素(相当于把c集合中包含在bookes集合中的元素删除掉)c.removeAll(books);System.out.println(c);//[6]//删除c集合里的所有元素c.clear();System.out.println("c集合中的元素:"+c);//c集合中的元素:[]//判断c集合是否为空System.out.println("c集合是否为空:"+c.isEmpty());//c集合是否为空:true//返回c集合中元素的个数System.out.println("c集合中元素个数:"+c.size());//c集合中元素个数:0//从books集合中删除c集合中不含有的元素books.retainAll(c);System.out.println("books集合中的元素:"+books);//books集合中的元素:[]}
}

tips:有关Collection中的方法可不止上面这些,其他方法可以自行查看API学习。

三、Set 集合

3.1 介绍

3.2 HashSet

HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高。

3.2.1 特点

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



HashSet会根据元素的hashCode值来计算它的存储位置,从而快速定位该元素的位置。

  • 当从HashSet中访问元素时,HashSet先计算该元素的hashCode()值(也就是调用该对象的hashCode()方法的返回值),然后直接到该hashCode值对应的位置去取出该元素----这就是HashSet速度很快的原因。

3.2.2 操作案例(重写hashCode和equals方法)

import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;class R{int count;public R(){}public R(int count){this.count  = count;}public String toString(){return "R[coutn:"+count+"]";}//重写的hashCode方法;//当HashSet集合对象调用add()方法时,//会拿该要添加的对象跟集合中已经添加的对象调用hashCode()方法进行比较。//从而来保证添加的元素不重复(跟equals方法同时协调使用)@Overridepublic int hashCode() {return this.count;}//重写的equals方法;//当HashSet集合对象调用add()方法时,//会拿该要添加的对象跟集合中已经添加的对象调用equals()方法进行比较。//从而来保证添加的元素不重复(跟hashCode方法同时协调使用)@Overridepublic boolean equals(Object obj) {if (this == obj){return false;}if (obj != null && obj.getClass() == getClass()){R r = (R)obj;return this.count == r.count;}return false;}
}public class HashSetTest2 {public static void main(String[] args) {R rr = new R(10);System.out.println(rr);//R[coutn:10]System.out.println(rr.toString());//R[coutn:10]HashSet<R> hs = new HashSet();hs.add(new R(2));hs.add(new R(-3));hs.add(new R(9));hs.add(new R(2));hs.add(new R(-5));//打印HashSet集合,集合元素没有重复System.out.println(hs);//[R[coutn:2], R[coutn:-3], R[coutn:-5], R[coutn:9]]//取出第一个元素Iterator it = hs.iterator();R first = (R)it.next();//为第一个元素的count实例变量赋值//导致HashSet集合中出现相同的值first.count = -3;System.out.println(hs);//[R[coutn:-3], R[coutn:-3], R[coutn:-5], R[coutn:9]]//删除count为-3的R对象hs.remove(new R(-3));System.out.println(hs);//[R[coutn:-3], R[coutn:-5], R[coutn:9]]//此时查看 new R(-3)(在原本第二个位置) 时出错,如下:System.out.println("hs是否包含count为-3的R对象?"+ hs.contains(new R(-3)));//falseSystem.out.println("hs是否包含count为-5的R对象?"+ hs.contains(new R(-5)));//trueSystem.out.println("hs是否包含count为2的R对象?"+ hs.contains(new R(2)));//false}
}

3.3 LinkedHashSet

LinkedHashSet,它是链表 和 哈希表组合的一个数据存储结构。

注意:输出LinkedHashSet集合元素时,元素的顺序总是与添加顺序一致。

import java.util.LinkedHashSet;
import java.util.LinkedList;public class LinkedHashSetTest {public static void main(String[] args) {LinkedHashSet books = new LinkedHashSet();books.add("疯狂原始人");books.add("寻梦环游记");System.out.println(books);//[疯狂原始人, 寻梦环游记]//删除 疯狂原始人books.remove("疯狂原始人");System.out.println(books);//[寻梦环游记]//重新添加books.add("疯狂原始人");System.out.println(books);//[寻梦环游记, 疯狂原始人]}
}

3.4 TreeSet

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。

与HashSet集合相比,TreeSet还提供了如下几个额外的方法:

  • Comparator comparator():如果TreeSet采用了制定排序,则该方法返回定制排序所使用的Compatator;如果TreeSet采用了自然排序,则返回null。
  • Object first():返回集合中的第一个元素。
  • Object last():返回集合中的最有一个元素。
  • Object lower(Object e):返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素不需要是TreeSet集合里的元素)。
  • Object higher(Object e):返回集合中位于指定元素之后的元素(即大于指定元素的最小值,参考元素不需要时TreeSet集合里的元素)。
  • SortedSet headSet(Object fromElement,Object toElement):返回Set的子集合,范围从fromElement(包含) 到 toElement(不包含)。
  • SortedSet headSet(Object toElement):返回此Set的子集,由小于toElement的元素组成。
  • SortedSet tailSet(Object fromElement):返回此Set的子集,由大于或等于fromElement的元素组成。


【案例】

import java.util.TreeSet;public class TreeSetTest {public static void main(String[] args) {TreeSet nums = new TreeSet();//向TreeSet中添加4个Integer对象nums.add(3);nums.add(2);nums.add(1);nums.add(-4);//输出集合元素,看到集合元素已经处于排序状态System.out.println(nums);//[-4, 1, 2, 3]//输出集合中的第一个元素System.out.println(nums.first());//-4//输出集合中的最后一个元素System.out.println(nums.last());//3//返回小于2的子集,不包含2System.out.println(nums.headSet(2));//[-4, 1]//返回大于1的子集,包含1System.out.println(nums.tailSet(1));//[1, 2, 3]//返回大于等于2小于4的子集System.out.println(nums.subSet(2,4));//[2, 3]}
}

3.4.1 自然排序





【案例】

import java.util.TreeSet;public class TreeSetTest {public static void main(String[] args) {TreeSet nums = new TreeSet();//向TreeSet中添加4个Integer对象nums.add(3);nums.add(2);nums.add(1);nums.add(-4);//输出集合元素,看到集合元素已经处于排序状态System.out.println(nums);//[-4, 1, 2, 3]}
}

3.4.2 定制排序(重点)


【案例】

import java.util.TreeSet;class M{int age;public M(int age){this.age = age;}public String toString(){return "M [age="+age+"]";}
}public class CustomizedSort {public static void main(String[] args) {//使用Lambda表达式来代替Comparator接口TreeSet ts = new TreeSet(((o1, o2) -> {M m1 = (M)o1;M m2 = (M)o2;//根据M对象的age属性来决定大小,age越大,M对象反而越小(降序)//return m1.age > m2.age ? -1 : m1.age < m2.age ? 1 :0;//根据M对象的age属性来决定大小,age越大,M对象越大(升序)return m1.age > m2.age ? 1 : m1.age < m2.age ? -1 : 0;}));ts.add(new M(5));ts.add(new M(-3));ts.add(new M(9));ts.add(new M(2));//降序时输出//System.out.println(ts);//[M [age=9], M [age=5], M [age=2], M [age=-3]]//升序时输出System.out.println(ts);//[M [age=-3], M [age=2], M [age=5], M [age=9]]}
}

四、List 集合

4.1 介绍

4.2 ArrayList

ArrayList 是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。

特点:查询效率高,增删效率低,线程不安全。

  • java.util.ArrayList 是大小可变的数组的实现,存储在内的数据称为元素。此类提供一些方法来操作内部存储的元素。 ArrayList 中可不断添加元素,其大小也自动增长。

4.3 LinkedList

LinkedList 底层用双向链表实现的存储。

特点:查询效率低,增删效率高,线程不安全。

五、Queue 集合

六、Map 集合

6.1 常用函数

Map接口中定义了很多方法,常用的如下:

  • int size():返回该Map里的key-value对的个数。

  • void clear():删除该Map对象中的所有 key-value 对。

  • boolean isEmpty():查询该Map是否为空(即不包含任何key-value对),如果为空则返回ture。

  • Object put(Object key, Object value): 添加一个 key-value 对,如果当前Map中已有一个与该key相等的 key-value 对,则心得key-value对会覆盖原来的key-value对。

  • void putAll(Map m):将指定Map中的 key-value 对复制到本Map中。

  • Object remove(Object key):删除指定key所对应的key-value对,返回被删除key所关联的value,如果该key不存在,则返回null。

  • Object remove(Object key,Object value):删除指定key、value所对应的key-value对。如果从该Map中成功删除该key-value对,该方法返回true,否则返回false。

  • Object get(Object key) :返回指定 key 所对应的value;如果此Map中不包含该key,则返回null。

  • boolean containsKey(Object key) :查询Map中是否包含指定的 key,如果包含则返回true。

  • boolean containsValue(Object value):查询Map中是否包含一个或多个value,如果包含则返回true。

  • Set<K> keySet():返回该Map中所有key组成的Set集合。

  • Collection values():返回该Map里所有value组成的Collection。

  • Set<Map.Entry<K,V>> entrySet(): 返回Map中包含的key-value 对所组成的Set集合,每个集合元素都是 Map.Entry(Entry是Map的内部类)对象。

6.2 HashMap

import java.util.HashMap;public class MapTest01 {public static void main(String[] args) {//创建map对象HashMap<String,String> map = new HashMap<>();//添加元素map.put("上","下");map.put("up","down");map.put("me","you");//添加元素返回该键值在map中对应的值(不是当前key的value)//如果map中没有该值,则返回nullSystem.out.println(map.put("xx","yy"));//nullSystem.out.println(map.put("xx","zz"));//yySystem.out.println(map);//{xx=zz, me=you, 上=下, up=down}//remove(V key) 返回所删除key值对应的valueSystem.out.println(map.remove("上"));//下System.out.println(map.remove("hhhh"));//nullSystem.out.println(map);//{xx=zz, me=you, up=down}//map.get(V key)获取 返回指定 key 所对应的value;如果此Map中不包含该key,则返回nullSystem.out.println("up的value:"+map.get("up"));//up的value:downSystem.out.println("hh的value:"+map.get("hh"));//hh的value:null}
}

集合遍历键找值【案例】

import java.util.HashMap;
import java.util.Set;public class FindKeysValue {public static void main(String[] args) {HashMap<String,String> map = new HashMap<>();map.put("数字","123");map.put("字母","abc");map.put("汉字","你好");//获取所有key,存入Set集合Set<String> keys = map.keySet();//遍历键集for (String key:keys){//根据key获得对应的valueString value = map.get(key);System.out.println(key+":对应的值是:"+value);}}
}


自定义类型键值【案例】

import java.util.Objects;//注意,学生姓名相同并且年龄相同视为同一名学生。
public class Student {private String name;private int 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;}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}//重写hashCode()方法@Overridepublic int hashCode() {return Objects.hash(name,age);}//重写equals()方法@Overridepublic boolean equals(Object obj) {if (this == obj){return true;}if (obj == null || getClass() != obj.getClass()){return false;}Student student = (Student) obj;return age == student.age && Objects.equals(name,student.name);}//重写toString()方法@Overridepublic String toString() {return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';}
}
public class HashMapCustomTest {public static void main(String[] args) {Map<Student,String> map = new HashMap<>();map.put(new Student("李四",28),"上海");map.put(new Student("王五",18),"广州");map.put(new Student("赵六",23),"南京");map.put(new Student("小红",13),"北京");map.put(new Student("许褚",32),"哈尔滨");map.put(new Student("刘备",23),"洛阳");//取出key值,存入Set集合Set<Student> ss = map.keySet();for (Student s:ss){//记得重写Student类中的toString方法,否则返回的是对象的地址System.out.println(s+" --> "+map.get(s));}}
}

  • 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
  • 如果要保证map中存放的key和取出的顺序一致,可以使用java.util.LinkedHashMap集合来存放。

tips:

  1. 使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中; 若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。

6.3 LinkedHashMap

HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?

在HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。

public class LinkHashMapTest {public static void main(String[] args) {LinkedHashMap<String,Integer> lmp = new LinkedHashMap<>();lmp.put("zhangsan",1);lmp.put("lisi",2);lmp.put("wangwu",3);Set<Map.Entry<String,Integer>> ss = lmp.entrySet();for (Map.Entry<String,Integer> s:ss){System.out.println("key:"+s.getKey()+",value:"+s.getValue());}}
}

6.4 Entry(内部类)

  我们已经知道,Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在Map中是一一对应关系,这一对对象又称做Map中的一个Entry(项)Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。

常用方法

  • Object getKey():返回该Entry里包含的key值。
  • Object getValue():返回该Entry里包含的value值。
  • Object setValue(V value):设置该Entry里包含的value值,并返回新设置的value值。

在Map集合中也提供了获取所有Entry对象的方法:

  • Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。

获取遍历

键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。

操作步骤与图解:

  1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示:Ojbect.entrySet()
  2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
  3. 通过键值对(Entry)对象,获取Entry对象中的键与值。 方法提示:getkey() 和 getValue()
public class MapEntryForeach {public static void main(String[] args) {HashMap<String,String> map = new HashMap<>();map.put("数字","123");map.put("字母","abc");map.put("汉字","你好");//获取所有 entry对象 ,entrySetSet<Map.Entry<String,String>> entrySet = map.entrySet();//遍历for (Map.Entry<String,String> entry: entrySet){//从entrySet对象中获取键String key = entry.getKey();//从entrySet对象中获取值String value = entry.getValue();System.out.println(key+"-->"+value);}}
}

七、Iterator 接口(迭代器)

7.1 介绍


  在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.IteratorIterator接口也是Java集合中的一员,但它与CollectionMap接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。

想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:

  • public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。

下面介绍一下迭代的概念:

  迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

7.2 常用方法

  • Object next():返回集合里的下一个元素。
  • boolean hasNext():如果仍有元素可以迭代,则返回 true。
  • void remove():删除集合里的上一次next方法返回的元素。
  • void forEachRemaining(Consumer action):jdk 1.8新增的默认方法,该方法可使用Lambda表达式来遍历集合元素。

使用Iterator迭代集合中元素:【案例】

public class IteratorTest {public static <Stirng> void main(String[] args) {//创建集合、添加元素Collection<String> books = new HashSet<>();books.add("疯狂原始人");books.add("元神");books.add("LOL");//获取books集合对应的迭代器Iterator it = books.iterator();System.out.println(it);//java.util.HashMap$KeyIterator@6d6f6e28System.out.println(it.next());//元神for (Iterator iter = it; iter.hasNext(); ) {String s = (String) iter.next();System.out.print(s+",");//疯狂原始人,LOL,}System.out.println();//直接使用next()方法如果集合中没有可迭代的下一个元素将发生异常//books.clear();//it.next();//java.util.ConcurrentModificationException//使用hasNext()方法判断books集合中是否还有下一个可迭代的元素while (it.hasNext()){//it.next()方法返回集合里的下一个元素//it.next()方法返回的数据类型是Object类型,因此需要进行强制类型转换String book = (String)it.next();System.out.println("book:"+book);//book:元神 //book:疯狂原始人 //book:LOLif (book.equals("元神")){//从集合中删除上一次next()方法返回的元素it.remove();}//对book变量赋值,不会改变集合元素本身book = "测试字符串";System.out.println(book);//测试字符串 //测试字符串 //测试字符串}System.out.println(books);//[疯狂原始人, LOL]}
}


tips

  1. 在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生java.util.ConcurrentModificationException并发异常。
  2. 当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

迭代器的实现原理

  当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。

  Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,为了让初学者能更好地理解迭代器的工作原理,接下来通过一个图例来演示Iterator对象迭代元素的过程:

  在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。

7.3 增强for(forEach)

  增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。

格式

for(元素的数据类型  变量 : Collection集合 或 数组){ //写操作代码
}

它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。

7.3.1 遍历数组

public class NBForDemo1 {public static void main(String[] args) {int[] arr = {3,5,6,87};//使用增强for遍历数组for(int a : arr){//a代表数组中的每个元素System.out.println(a);}}
}

7.3.2 遍历集合

public class NBFor {public static void main(String[] args) {        Collection<String> coll = new ArrayList<String>();coll.add("小河神");coll.add("老河神");coll.add("神婆");//使用增强for遍历for(String s :coll){//接收变量s代表 代表被遍历到的集合元素System.out.println(s);}}
}

tips:新for循环必须有被遍历的目标。目标只能是Collection或者是数组。新式for仅仅作为遍历操作出现。

八、Collections 工具类

java.util.Collections 类提供了对Set、List、Map集合进行排序、填充、查找元素的辅助方法。

8.1 排序

常用方法

  • void reverse(List list):反转指定List集合中元素顺序。
  • void shuffle(List list):对List集合元素进行随机排序(shuffle方法模拟了“洗牌”动作)。
  • void sort(List list):根据元素的自然顺序对指定List集合的元素按升序进行排序。
  • void sort(List list,Comparator c):根据指定Comparator产生的顺序对List集合元素进行排序。
  • void swap(List list,int i,int j):将指定List集合中的 i 处的元素和 j 处的元素进行交换。
  • void rotate(List list,int distance):当distance为正数时,将list集合的后distance个元素“整体”移到前面;当distance为负数时,将list集合的前distance个元素“整体”移到后面。该方法不会改变集合的长度。

8.2 查找、替换

  • int binarySearch(List list, Object key), 对List进行二分查找,返回索引,注意List必须是有序的
  • int max(Collection coll),根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll)
  • int max(Collection coll, Comparator c),根据定制排序,返回最大元素,排序规则由Comparatator类控制。类比int min(Collection coll, Comparator c)
  • void fill(List list, Object obj),用元素obj填充list中所有元素
  • int frequency(Collection c, Object o),统计元素出现次数
  • int indexOfSubList(List list, List target), 统计targe在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target).
  • boolean replaceAll(List list, Object oldVal, Object newVal), 用新元素替换旧元素。

8.3 Comparable 接口

8.3.1 单条件 排序

如果想使用Collections.sort(List list);对 对象集合 进行指定规则的排序,则该对象所在的类必须继承Comparable< E >接口,否则报错。

public class StudentImplementComparable implements Comparable<StudentImplementComparable>{private int age;private String name;private double weight;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}public StudentImplementComparable() {}public StudentImplementComparable(int age, String name, double weight) {this.age = age;this.name = name;this.weight = weight;}@Overridepublic String toString() {return "StudentImplementComparable{" +"age=" + age +", name='" + name + '\'' +", weight=" + weight +'}';}@Overridepublic int compareTo(StudentImplementComparable o) {//按年龄升序排列return (this.age < o.age) ? -1 : ((this.age == o.age) ? 0 : 1);//按年龄降序排列//return -((this.age < o.age) ? -1 : ((this.age == o.age) ? 0 : 1));}
}
public class StudentImplementComparableTest {public static void main(String[] args) {ArrayList<StudentImplementComparable> sl = new ArrayList<>();
//        sl.add(new StudentImplementComparable(12,"张三",12.3));
//        sl.add(new StudentImplementComparable(15,"李四",33.1));
//        sl.add(new StudentImplementComparable(20,"王五",25.2));
//        sl.add(new StudentImplementComparable(10,"许褚",10.0));Collections.addAll(sl,new StudentImplementComparable(12,"张三",12.3),new StudentImplementComparable(15,"李四",33.1),new StudentImplementComparable(20,"王五",25.2),new StudentImplementComparable(10,"许褚",10.0));Collections.sort(sl);//调用排序方法(调用sl集合对象所在类里面重写的comparaTo(E e)方法)for (StudentImplementComparable s: sl) {System.out.println(s);}}
}


8.3.2 多条件 排序

 //修改重写的 compareTo 方法@Overridepublic int compareTo(StudentImplementComparable o) {//按年龄升序排列//return (this.age < o.age) ? -1 : ((this.age == o.age) ? 0 : 1);//按年龄降序排列//return -((this.age < o.age) ? -1 : ((this.age == o.age) ? 0 : 1));//按照年龄升序排列,年龄相同的话再按体重升序排列if (this.age == o.age){return (this.weight < o.weight) ? -1 : ((this.weight == o.weight) ? 0 : 1);}else{return (this.age < o.age) ? -1 : 1;}}
     Collections.addAll(sl,new StudentImplementComparable(12,"张三",12.3),new StudentImplementComparable(15,"李四",33.1),new StudentImplementComparable(20,"王五",25.2),new StudentImplementComparable(20,"刘备",56.8),new StudentImplementComparable(10,"许褚",10.0));Collections.sort(sl);for (StudentImplementComparable s: sl) {System.out.println(s);}

8.4 Comparator 接口

void Collections.sort(List<T> list,Comparator<? super T> c)

public class StudentImplementComparable {private int age;private String name;private double weight;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}public StudentImplementComparable() {}public StudentImplementComparable(int age, String name, double weight) {this.age = age;this.name = name;this.weight = weight;}@Overridepublic String toString() {return "StudentImplementComparable{" +"age=" + age +", name='" + name + '\'' +", weight=" + weight +'}';}
}
public class StudentImplementComparableTest {public static void main(String[] args) {ArrayList<StudentImplementComparable> sl = new ArrayList<>();
//        sl.add(new StudentImplementComparable(12,"张三",12.3));
//        sl.add(new StudentImplementComparable(15,"李四",33.1));
//        sl.add(new StudentImplementComparable(20,"王五",25.2));
//        sl.add(new StudentImplementComparable(10,"许褚",10.0));Collections.addAll(sl,new StudentImplementComparable(12,"张三",12.3),new StudentImplementComparable(15,"李四",33.1),new StudentImplementComparable(20,"王五",56.8),new StudentImplementComparable(20,"刘备",25.2),new StudentImplementComparable(10,"许褚",10.0));System.out.println("Comparator接口实现自定义排序");//Comparator接口实现自定义排序Collections.sort(sl, new Comparator<StudentImplementComparable>() {@Overridepublic int compare(StudentImplementComparable o1, StudentImplementComparable o2) {//年龄升序//return o1.getAge() - o2.getAge();//年龄降序//return o2.getAge() - o1.getAge();//年龄升序,如果年龄相同则按体重升序排列if (o1.getAge() == o2.getAge()){return (int)(o1.getWeight() - o2.getWeight());}else{return o1.getAge() - o2.getAge();}}});for (StudentImplementComparable s:sl) {System.out.println(s);}}
}

九、遍历集合的四种方式

9.1 方式一:Lambda 表达式遍历集合

public class CollectionEach {public static void main(String[] args) {//创建一个集合Collection books = new HashSet();books.add("疯狂原始人");books.add("寻梦环游记");books.add("时空恋人");//调用forEach()方法遍历集合books.forEach(obj -> System.out.println("迭代books集合元素:"+obj));}
}

9.2 方式二:Iterator 遍历集合

public class IteratorTest {public static <Stirng> void main(String[] args) {//创建集合、添加元素Collection<String> books = new HashSet<>();books.add("疯狂原始人");books.add("元神");books.add("LOL");//1.获取books集合对应的迭代器Iterator it = books.iterator();System.out.println(it);//java.util.HashMap$KeyIterator@6d6f6e28System.out.println(it.next());//元神for (Iterator iter = it; iter.hasNext(); ) {String s = (String) iter.next();System.out.print(s+",");//疯狂原始人,LOL,}System.out.println();//直接使用next()方法如果集合中没有可迭代的下一个元素将发生异常//books.clear();//it.next();//java.util.ConcurrentModificationException//2.使用hasNext()方法判断books集合中是否还有下一个可迭代的元素while (it.hasNext()){//3.it.next()方法返回集合里的下一个元素//it.next()方法返回的数据类型是Object类型,因此需要进行强制类型转换String book = (String)it.next();System.out.println("book:"+book);//book:元神 //book:疯狂原始人 //book:LOLif (book.equals("元神")){//从集合中删除上一次next()方法返回的元素it.remove();}//对book变量赋值,不会改变集合元素本身book = "测试字符串";System.out.println(book);//测试字符串 //测试字符串 //测试字符串}System.out.println(books);//[疯狂原始人, LOL]}
}

9.3 方式三:Lambda 表达式遍历 Iterator

public class ForEachIteratorTest {public static void main(String[] args) {//创建集合、添加元素Collection<String> books = new HashSet<>();books.add("疯狂原始人");books.add("元神");books.add("LOL");//获取books集合对应的迭代器Iterator it = books.iterator();//使用Lambda表达式(目标类型是Comsumer)来遍历集合元素it.forEachRemaining(obj -> System.out.println("迭代books集合元素:" + obj));}
}

9.4 方式四:foreach 循环遍历集合

public class ForeachCollectionTest {public static void main(String[] args) {Collection<String> books = new ArrayList<>();books.add("java");books.add("php");books.add("python");System.out.println("books有序集合中的元素:"+books);//books有序集合中的元素:[java, php, python]//foreach遍历books有序集合for (String s:books) {//此处的s变量不是集合元素本身System.out.print(s+",");//java,php,python,if (s.equals("python")){//下面代码会引发 ConcurrentModificationException 异常//集合元素在遍历时不可进行修改!!!【注意】//books.remove(s);}}System.out.println();System.out.println("books有序集合中的元素:"+books);//books有序集合中的元素:[java, php, python]}
}

Java知识点04——集合(Set、List、Queue、Map、Collection和Iterator、Collections工具类)相关推荐

  1. Java集合框架:Collections工具类

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  2. Java—遍历集合的N种方式总结Collections工具类

    遍历集合的N种方式总结 [示例1]遍历List方法1,使用普通for循环 for(int i=0;i<list.size();i++){         //list为集合的对象名 String ...

  3. 集合框架(Map容器/Collections工具类)

    >两大主流:collection.map(接口) 底层实现为数组和链表: RationalRose工具:接口与典型实现类: Map为key和value对的形式; >HashMap(线程不安 ...

  4. 集合之Map家族的TreeMap + Sort +Properties及Collections工具类和总结

    集合之Map家族的TreeMap + Sort +Properties及Collections工具类和总结 一.TreeMap 1.TreeMap的使用 import java.util.Arrays ...

  5. JavaSE学习总结(十四)Map集合/Map和Collection的区别/HashMap/LinkedHashMap/TreeMap/集合间的嵌套/Hashtable/Collections工具类

    一.Map集合 我们知道,一个学号就能对应一个学生,并且每个学生的学号都不同,学号就像一个键,对应的学生就是该键对应的值.日常生活中经常能见到这种类似学号对应学生的例子.Java 为了我们更加方便地去 ...

  6. 集合框架学习笔记:Collection体系和Map体系、Collections工具类

    集合框架 Java是面向对象编程,万事万物皆"对象",为了方便对"对象"进行操作,需要对"对象"进行存储,而Java集合就是存储" ...

  7. Java中集合相关案例(泛型通配符、Collections工具类、TreeSet、TreeMap、HashMap、HashSet和集合嵌套案例)

    集合 一.集合相关案例 1.泛型通配符案例 2.集合工具类(Collections工具类) 3.TreeSet和TreeMap案例 4.HashMap案例 5.HashSet案例 6.TreeSet案 ...

  8. Day18JavaSE——Map集合Collections工具类集合案例练习

    Day18JavaSE--Map集合&Collections工具类&集合案例练习 文章目录 Day18JavaSE--Map集合&Collections工具类&集合案例 ...

  9. java(五)-迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类

    day05[迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类] 主要内容 Collection集合的遍历方式: 迭代器. foreach(增强for循环) JDK ...

最新文章

  1. 第二课.Python编程基础(一)
  2. COCO数据集数据转换为XML格式
  3. SQL命令大全-中英文对照
  4. python爬携程酒店评论_python爬虫爬取携程网的酒店评论数据时,有个请求参数不知道是怎么生成的?...
  5. 图解Java中的18 把锁!
  6. 汇总丨MySQL GTID技术点,看这一篇就够了!
  7. mysql计算折纸_mysql数据库的创建和授权
  8. 史上最全的面试宝典,让你轻松入职
  9. AutoCAD2010图边框图.LSP与.DGW文件该放在哪才能正确生成想要的图框
  10. html发布机制tacat,序列分析一般程序中的一个实例
  11. 100个经典C语言程序(益智类问题)
  12. 线性组合(linear combinations), 生成空间(span), 基向量(basis vectors)——线性代数本质(二)
  13. 魔兽争霸——《冰封王座》2007魔兽比赛背景音乐下载
  14. 计算机上的数学符号怎么打平方,平方米符号电脑上怎么打
  15. golang并发编程之Ticker
  16. 齐岳|脂质体磷酸钙纳米粒RNA核糖核酸|淫羊藿苷固体纳米脂质体(ICA-SLN)修饰负载RNA核糖核酸
  17. ui设计师需要学哪些软件
  18. [Python3] 超级码力在线编程大赛初赛 第2场 题解
  19. 搭建一个电商app系统软件要多少钱
  20. png序列帧转换WebP动画

热门文章

  1. 谷歌浏览器地址转换成二维码的插件,只需几行代码即可实现
  2. 宏观经济笔记--CPI和PPI
  3. vue中使用document.getelementbyid为null
  4. Android电视开机倒计时,一种智能电视开机视频的倒计时方法与流程
  5. Python-Django毕业设计黑河市劳务人员管理系统(程序+Lw)
  6. Spring的日志模块-spring-jcl源码解析以及Java的日志框架
  7. cousins什么意思_cousins怎么读什么意思
  8. 区块链小媒体还能蹦跶几天,苹果的双卡双待才是王道!
  9. iphone个系列尺寸_乔帮主再被打脸,库克觉得iPhone将需要手写笔
  10. 传奇私服双击自动触发脚本