1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Java知识点04——集合(Set List Queue Map Collection和Iterator Collections工具类)

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

时间:2018-09-29 19:24:55

相关推荐

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

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

一、集合1.1 集合概述二、Collection2.1 介绍2.2 操作集合2.3 操作案例三、Set 集合3.1 介绍3.2 HashSet3.2.1 特点3.2.2 操作案例(重写hashCode和equals方法)3.3 LinkedHashSet3.4 TreeSet3.4.1 自然排序3.4.2 定制排序(重点)四、List 集合4.1 介绍4.2 ArrayList4.3 LinkedList五、Queue 集合六、Map 集合6.1 常用函数6.2 HashMap6.3 LinkedHashMap6.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 表达式遍历 Iterator9.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.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

在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的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]}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。