Java知识点04——集合(Set、List、Queue、Map、Collection和Iterator、Collections工具类)
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 循环遍历集合
声明:
- 该资料来自自己整理。
- 参考书籍
疯狂 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:
- 使用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)对象中的键与值。
操作步骤与图解:
- 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示:
Ojbect.entrySet()
。 - 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
- 通过键值对(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.Iterator
。Iterator
接口也是Java集合中的一员,但它与Collection
、Map
接口有所不同,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
- 在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生java.util.ConcurrentModificationException并发异常。
- 当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
迭代器的实现原理
当遍历集合时,首先通过调用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工具类)相关推荐
- Java集合框架:Collections工具类
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- Java—遍历集合的N种方式总结Collections工具类
遍历集合的N种方式总结 [示例1]遍历List方法1,使用普通for循环 for(int i=0;i<list.size();i++){ //list为集合的对象名 String ...
- 集合框架(Map容器/Collections工具类)
>两大主流:collection.map(接口) 底层实现为数组和链表: RationalRose工具:接口与典型实现类: Map为key和value对的形式; >HashMap(线程不安 ...
- 集合之Map家族的TreeMap + Sort +Properties及Collections工具类和总结
集合之Map家族的TreeMap + Sort +Properties及Collections工具类和总结 一.TreeMap 1.TreeMap的使用 import java.util.Arrays ...
- JavaSE学习总结(十四)Map集合/Map和Collection的区别/HashMap/LinkedHashMap/TreeMap/集合间的嵌套/Hashtable/Collections工具类
一.Map集合 我们知道,一个学号就能对应一个学生,并且每个学生的学号都不同,学号就像一个键,对应的学生就是该键对应的值.日常生活中经常能见到这种类似学号对应学生的例子.Java 为了我们更加方便地去 ...
- 集合框架学习笔记:Collection体系和Map体系、Collections工具类
集合框架 Java是面向对象编程,万事万物皆"对象",为了方便对"对象"进行操作,需要对"对象"进行存储,而Java集合就是存储" ...
- Java中集合相关案例(泛型通配符、Collections工具类、TreeSet、TreeMap、HashMap、HashSet和集合嵌套案例)
集合 一.集合相关案例 1.泛型通配符案例 2.集合工具类(Collections工具类) 3.TreeSet和TreeMap案例 4.HashMap案例 5.HashSet案例 6.TreeSet案 ...
- Day18JavaSE——Map集合Collections工具类集合案例练习
Day18JavaSE--Map集合&Collections工具类&集合案例练习 文章目录 Day18JavaSE--Map集合&Collections工具类&集合案例 ...
- java(五)-迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类
day05[迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类] 主要内容 Collection集合的遍历方式: 迭代器. foreach(增强for循环) JDK ...
最新文章
- 第二课.Python编程基础(一)
- COCO数据集数据转换为XML格式
- SQL命令大全-中英文对照
- python爬携程酒店评论_python爬虫爬取携程网的酒店评论数据时,有个请求参数不知道是怎么生成的?...
- 图解Java中的18 把锁!
- 汇总丨MySQL GTID技术点,看这一篇就够了!
- mysql计算折纸_mysql数据库的创建和授权
- 史上最全的面试宝典,让你轻松入职
- AutoCAD2010图边框图.LSP与.DGW文件该放在哪才能正确生成想要的图框
- html发布机制tacat,序列分析一般程序中的一个实例
- 100个经典C语言程序(益智类问题)
- 线性组合(linear combinations), 生成空间(span), 基向量(basis vectors)——线性代数本质(二)
- 魔兽争霸——《冰封王座》2007魔兽比赛背景音乐下载
- 计算机上的数学符号怎么打平方,平方米符号电脑上怎么打
- golang并发编程之Ticker
- 齐岳|脂质体磷酸钙纳米粒RNA核糖核酸|淫羊藿苷固体纳米脂质体(ICA-SLN)修饰负载RNA核糖核酸
- ui设计师需要学哪些软件
- [Python3] 超级码力在线编程大赛初赛 第2场 题解
- 搭建一个电商app系统软件要多少钱
- png序列帧转换WebP动画
热门文章
- 谷歌浏览器地址转换成二维码的插件,只需几行代码即可实现
- 宏观经济笔记--CPI和PPI
- vue中使用document.getelementbyid为null
- Android电视开机倒计时,一种智能电视开机视频的倒计时方法与流程
- Python-Django毕业设计黑河市劳务人员管理系统(程序+Lw)
- Spring的日志模块-spring-jcl源码解析以及Java的日志框架
- cousins什么意思_cousins怎么读什么意思
- 区块链小媒体还能蹦跶几天,苹果的双卡双待才是王道!
- iphone个系列尺寸_乔帮主再被打脸,库克觉得iPhone将需要手写笔
- 传奇私服双击自动触发脚本