主页 > 软件开发  > 

了解Java集合的概念和体系:Collection<T>、Collections与Stream的使用

了解Java集合的概念和体系:Collection<T>、Collections与Stream的使用
学习目标

本文知识是对集合层级的介绍,应用开发中实际使用的是他们的子级,感兴趣的小伙伴或者想深入了解有关Java集合知识的朋友可以选择阅读!

Stream的方法使用使用部分代码块内大多有两种实现方式,是为了更好的理解方法底层的代码,不必过于深究,可以看懂链式应用的方法即可

核心掌握集合层级了解Collection了解Collections了解Stream 1.集合概念

● 集合和数组一样也是容器,但是只能放对象 ● 集合和数组相比,数组长度是固定的(一旦确定之后不能改动) 集合长度不限 ● 数组中数组元素要求数据类型一致;集合中可以放任意的对象(只能是对象 ,只不过对象类型不要求一致) ● 集合中不能放基本数据类型,只能放对象 ● 集合中有比较多的数据结构 可供选择

2.集合体系

3.集合分类

● 有2大类的集合: 存储的数据特征。 ● 1、Collection接口: 数据只能是单值(一个个的数据) 每次存储一个元素/数据 ● 问题: 元素是否可重复? 元素是否有序(索引位置)? List: 元素有序可重复 Set: 元素无序且唯一

● 2、Map<K,V> 接口 : 数据必须是一组元素(2个数据) 有key–value ● key: 必须唯一 ● value: 可以重复

4.Collection<T>

● java.util.Collection ● 表示集合层次的根接口。 ● 存储单值元素。

4.1 层级 public interface Collection<E> extends Iterable<E>{} 4.2 常用方法

4.3 使用方法 无泛型 public static void collectionMethod() { Collection arrayList = new ArrayList(); Collection arrayList2 = new ArrayList(); arrayList2.add(66); arrayList2.add(99); // 自动装箱 1 int-->Integer arrayList.add(10); String a = "abc"; arrayList.add(99); System.out.println("添加是否成功:" + arrayList.add(a)); System.out.println("集合是否为空,没有集合元素:" + arrayList.isEmpty()); // Integer是不可变的 ,一旦改值 那就是新的对象 System.out.println("移除Integer是否成功:" + arrayList.remove(2)); // remove进行移除的时候,看集合中是否包含这个对象 如果有那么移除成功 // System.out.println("移除stringBuilder是否成功:" + arrayList.remove(stringBuilder)); System.out.println("集合中的元素个数:" + arrayList.size()); String b = "abc"; System.out.println("集合中是否包含某个元素:" + arrayList.contains(b)); // 一次性 添加多个元素进来 //arrayList.addAll(arrayList2); System.out.println("addAll:" + arrayList); // arrayList.removeAll(arrayList2);// 只要元素和arrayList2相等 就删除 System.out.println("removeAll:" + arrayList); // System.out.println("containsAll 全部包含: " + arrayList.containsAll(arrayList2)); //移除所有元素 arrayList.clear(); } 有泛型 private static void demo1() { //1.创建集合对象 Collection collection = new ArrayList(); //2.操作 //2.1 新增 collection.add("hello"); collection.add("hello"); collection.add(100); collection.add(true); collection.add(10.123); collection.add(null); collection.add(new UserInfo("张三")); //2.2 查看集合元素个数 System.out.println(collection.size()); //2.3 删除 collection.remove("hello"); collection.remove("hello"); /* collection.removeIf(new Predicate() { @Override public boolean test(Object obj) { return "hello".equals(obj); } });*/ //collection.removeIf("hello"::equals); //collection.clear(); //2.4判断 System.out.println(collection.contains(1000)); System.out.println(collection.isEmpty()); System.out.println(collection.size()==0); System.out.println(collection.size()); System.out.println(collection.toString());// } 4.4 遍历集合 集合迭代器常用方法 private static void demo2() { Collection<Integer> collection = new ArrayList<>(); //java.util.Collections工具类 操作集合元素静态方法 Arrays Collections.addAll(collection, 10, 20, 30, 1, 5); //遍历集合元素的方式: 其实就1种遍历集合的方式(迭代器) // 2. 增强for // 增强for遍历数组: class文件里面还是普通for循环 // 增强for遍历集合: class文件里面使用的iterator遍历集合元素的 for (Integer num : collection) { System.out.println("num:"+num); } // 3. Iterator<E> iterator() 获得集合的迭代器对象 //3.1 获得集合的迭代器对象 Iterator<Integer> iterator = collection.iterator();//集合的数据都在iterator里面了 //3.2 判断光标之后是否有数据 while (iterator.hasNext()){ //3.3 获得光标之后的数据 Integer num = iterator.next(); System.out.println("num:"+num); } // 4. default void forEach(Consumer<? super T> action) 遍历集合元素 jdk1.8+ /*collection.forEach(new Consumer<Integer>() { @Override public void accept(Integer num) { System.out.println(num); } });*/ collection.forEach(System.out::println); System.out.println(collection); } 4.5 集合转数组 private static void demo3() { Collection<Integer> collection = new ArrayList<>(); collection.add(100);//装箱 collection.add(200); collection.add(300); //集合转数组----> 数组操作比较复杂 //3. default <T> T[] toArray(IntFunction<T[]> generator); //第3个方法 与第2个方法的思想一致的。 length=0 Integer[] integers = collection.toArray(new IntFunction<Integer[]>() { @Override public Integer[] apply(int value) {//0 System.out.println("value:" + value); return new Integer[value]; } }); Integer[] integers = collection.toArray(Integer[]::new); System.out.println("integers:"+Arrays.toString(integers)); //2. <T> T[] toArray(T[] a); 建议使用 核心:数组 Integer[] numArray = new Integer[0]; //2.1 length==collection.size() 保证数组里面存储size个元素 //2.2 length>collection.size() 问题: 数组的空间比较大的 null----> 功能实现 有可能会出现NPE //2.3 length<collection.size() 可以转换成功 //站在并发/性能/扩容: 建议指定的数组的length=0 Integer[] toArray = collection.toArray(numArray); System.out.println("numArray:" + Arrays.toString(numArray)); System.out.println("toArray:" + Arrays.toString(toArray)); System.out.println(numArray == toArray); Object[] array = collection.toArray(); //1. 不要使用Object[] toArray() 不管集合里面存储什么类型的数据 都要转成一个Object[] for (Object obj : array) { Integer num = (Integer) obj; System.out.println(num + 100); } System.out.println(Arrays.toString(array)); } 4.6 匿名内部类

● 在任意一个类和接口都能创建匿名内部类,相当于定义了一个 没有名字的新的类。 ● 等价于创建了一个类的子类,以及接口的实现类。

创建接口 public interface MyInterface { void method1(); } 创建匿名内部类 public static void main(String[] args) { // 匿名内部类 抽象类 和接口都能使用 test(new MyInterface() { @Override public void method1() { System.out.println("method111==="); } });//等价于接口的实类对象 } public static void test(MyInterface myInter) { myInter.method1(); } public static void test1(){ Object obj = new Object(){ //等价于类的匿名内部类---->类的子类 } } 提醒(可以先看这部分)

● 虽然我们讲解了集合的根接口Collection以及相关的方法。 ● 但是在开发中一般不用父接口,用的还是子级,List或者Set ● 我们只需要知道Collection里面维护的都是List以及Set集合都有的方法即可。

5.Collections的使用

● 工具类。在java.util包。 ● 类似于之前学的Arrays。 ● Collections操作集合(Collection->List/Set)元素的工具类

常用方法 private static void demo1() { //1.Collections.addAll(Collection,T...data); 将多个数据新增到指定的集合对象中 List<Integer> list = new ArrayList<>(10); //list.add(10); Collections.addAll(list, 10, 10, 1, 3, 4, 50, 24, 100); Set<Integer> set = new HashSet<>(16); Collections.addAll(set, 10, 10, 1, 3, 4, 50, 24, 100); List<Integer> list1 = List.of(1, 2, 3);//只能读数据 Set<Integer> set1 = Set.of(1, 2, 3, 4, 5); Map<Integer, Integer> map = Map.of(1, 1, 2, 2, 3, 3, 4, 4); //数组转集合 List<Integer> list2 = Arrays.asList(1, 2, 3); } 常用的静态常量 private static List<?> demo3() { //获得一个空集合对象 等价于size=0 System.out.println(Collections.EMPTY_LIST);//[] System.out.println(Collections.EMPTY_MAP);//{} System.out.println(Collections.EMPTY_SET);//[] System.out.println(Collections.emptySet()); System.out.println(Collections.emptyMap()); System.out.println(Collections.emptyList()); //前提: 方法的返回值是特定的集合类型 //在功能里面 可以作为返回值使用 判断的时候避免出现NPE return Collections.EMPTY_LIST; } private static void demo2() { //2.将线程不安全的集合对象转换成线程安全的集合对象 可以在并发的环境下 作为全局变量使用 Collections.synchronizedList(new ArraysList()); Vector Collections.synchronizedSet(new HashSet()) Collections.synchronizedMap(new HashMap()) ConcurrentHashMap //以下2个方法 只针对于TreeMap与TreeSet Collections.synchronizedSortedMap(new TreeMap()) Collections.synchronizedSortedSet(new TreeSet()) } sort private static void demo4() { //Collections.sort(List); 要求集合元素类型必须实现Comparable //Collections.sort(List,Comparator); //如果真的是对list集合排序,一般我们只会使用List.sort() List<Integer> list = new ArrayList<>(10); Collections.addAll(list, 10, 10, 1, 3, 4, 50, 24, 100); Collections.sort(list); System.out.println(list); System.out.println("-----------------------"); List<UserInfo> userInfoList = new ArrayList<>(10); Collections.addAll(userInfoList, new UserInfo(1, "jim", 20), new UserInfo(2, "tom", 18), new UserInfo(3, "lilei", 23), new UserInfo(4, "hanmeimei", 16) ); //Collections.sort(userInfoList, Comparator paring(UserInfo::getAge)); userInfoList.sort(Comparator paring(UserInfo::getAge).reversed()); userInfoList.forEach(System.out::println); } 获得集合的最值 private static void demo5() { TreeSet<Integer> set = new TreeSet<>(); Collections.addAll(set, 10, 10, 1, 3, 4, 50, 24, 100); System.out.println(set);//[1, 50, 3, 4, 100, 24, 10] //获得Set集合的最值 //1.TreeSet System.out.println(set.first()); System.out.println(set.last()); System.out.println("------------------------------------"); Set<Integer> hashSet = new HashSet<>(16); Collections.addAll(hashSet, 10, 10, 1, 3, 4, 50, 24, 100); //Collections.sort(List); 只能对list集合排序 不能对set集合排序 //5. 最值 Collections.max(Collection); 集合元素类型必须实现Comparable Collections.max(Collection,Comparator); Collections.min(Collection); Collections.min(Collection,Comparator); Integer max = Collections.max(hashSet); Integer min = Collections.min(hashSet); System.out.println(max); System.out.println(min); } shuffle private static void demo6() { // Collections.shuffle(List); 随机(随机数)打乱集合元素顺序。 洗牌。 List<Integer> list = new ArrayList<>(10); Collections.addAll(list, 10, 1, 3, 4, 50, 24); System.out.println(list); Collections.shuffle(list); System.out.println(list); } 6.Stream

● 丰富了对Collection(List,Set)的操作 ● 可以看成是一个增强版的迭代器。数据源不限,可以是多个数据源(Collection集合对象) ● 中间操作 属于 惰性操作 只有碰到终止操作才会执行 ○ 凡是返回值是Stream类型的都是中间操作 ○ filter:对流中数据进行过滤:返回值为 true表示留下的数据 false表示过滤掉的 ○ map: 把流中的每个数据经过相同的操作 映射为新的数据 ○ sorted:对流中数据排序 ○ limit :只保留指定个数的元素 ○ peek:表示查看 流中元素 ● 终止操作 ○ 只要返回值不是Stream类型的 ○ count:得到流中元素个数 ○ reduce:合并 合并为一个数据 ○ collect:流数据的收集 ● Stream对象流是一次性的,只能被操作一次,不能重复操作 ● 终止操作只能出现一次,在最后出现

6.1 获得Stream private static void demo1() { //获得Stream的方式 //1. 根据集合对象操作。Collection.stream()/paraStream() List<Integer> list = Arrays.asList(1, 2, 3, 4); Stream<Integer> stream = list.stream();//串行化流 集合的数据都在Stream里面 Stream<Integer> stream1 = list.parallelStream();//并行化流 Iterator<Integer> iterator = list.iterator(); //2. 使用Stream接口里面的静态方法 Stream.concat(Stream,Stream); Stream<Integer> stream2 = Stream.of(1, 2, 3); //3.Arrays.stream() //IntStream LongStream DoubleStream //避免过多拆箱和装箱 提供了操作基本数据类型数据的Stream IntStream stream2 = Arrays.stream(new int[]{1, 2, 3}); //4.Random.ints() //随机数Random //获得10个随机的数字。 0 200随机的数据 Random random = new Random(); int num = random.nextInt(200); IntStream intStream = random.ints(10, 100, 200); String str = "hello"; IntStream intStream1 = str.chars(); } 6.2 操作Stream Stream Stream.distinct() ; 去重Stream Stream.sorted() ; 排序Stream Stream.sorted(Comparator<? super T> comparator) ; 根据外部比较器排序规则排序Stream Stream skip(long n); 跳过数据源里面指定数量的数据Optional Stream.max(Comparator<? super T> comparator) ; 获得最值Optional Stream.min(Comparator<? super T> comparator) ;Stream.limit(long maxSize) ; 对数据源的数量限定Stream.forEach(Consumer<? super T> action) 循环遍历Stream.count(); 统计Stream里面的元素个数Stream.findAny() ; 查询任意一个数据Stream.findFirst() ;collect(Collector<? super T,A,R> collector) //收集操作之后的数据 存储到一个新的集合对象中 1.distinct/sort private static void demo2() { List<Integer> list = Arrays.asList(1, 2, 3, 4, 20, 2, 1, 3); //对list集合元素进行去重/排序(降序) //1.获得Stream对象 Stream<Integer> stream = list.parallelStream(); //2.操作Stream Stream<Integer> stream1 = stream.distinct(); Stream<Integer> stream2 = stream1.sorted(Comparator.reverseOrder()); //3.获得操作之后满足条件的一些数据 存储到一个新的集合中---->收集起来 终止Stream List<Integer> resultList = stream2.collect(Collectors.toList()); System.out.println(resultList);*/ //Stream就是一次性的。 //查询Stream里面还有多少个数据 终止Stream之后 无法再对Stream的数据进行相关的处理 //操作Stream: 一般都是方法链的方式 List<Integer> list1 = list.parallelStream().distinct().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); System.out.println(list1); } 2.allMatch/anyMatch private static void demo3() { List<String> list = List.of("hellom", "jiy", "toc"); //判断list集合的每个元素是否都包含指定的 m这个数据 for (int index = 0; index < list.size(); index++) { String str = list.get(index); if(str==null) break; if(!str.contains("m")){ System.out.println(false); return; } } System.out.println(true); System.out.println("----------------------------"); boolean flag = list.parallelStream().allMatch(new Predicate<String>() { @Override public boolean test(String s) { return s.contains("m"); } }); boolean flag = list.stream().anyMatch(str -> str.contains("m")); System.out.println(flag); } 3.filter

Stream filter(Predicate<? super T> predicate) ;//过滤Stream中不满足条件的数据

private static void demo4() { List<String> list = List.of("zhangsan", "jim", "tom","lisi"); //获得list集合中: 过滤下来元素里面包含m的数据 List<String> nameList = new ArrayList<>(10); for (String name : list) { if(name.contains("m")){ nameList.add(name); } } System.out.println("----------------------------"); List<String> stringList = list.parallelStream() .filter(name -> name.contains("m")).collect(Collectors.toList()); System.out.println(stringList); } 4.findFirst/findAny/min private static void demo5() { List<UserInfo> userInfoList = new ArrayList<>(10); Collections.addAll(userInfoList, new UserInfo(1, "jim", 20), new UserInfo(2, "tom", 18), new UserInfo(3, "lilei", 23), new UserInfo(4, "hanmeimei", 16) ); //获得年龄>=20的用户 List<UserInfo> collect = userInfoList.stream().filter(userInfo -> userInfo.getAge() >= 20).collect(Collectors.toList()); //使用lambda表达式 collect.forEach(System.out::println); //获得userInfoList年龄最小的用户对象 //1.正常编写 userInfoList.sort(Comparator paring(UserInfo::getAge)); UserInfo userInfo = userInfoList.get(0); System.out.println(userInfo); System.out.println("-------------------"); userInfoList.forEach(System.out::println); //或用Collections.min() //2.Stream Optional<UserInfo> first = userInfoList.stream().sorted(Comparator paring(UserInfo::getAge)).findFirst(); System.out.println(first); System.out.println("-------------------"); userInfoList.forEach(System.out::println); System.out.println("----------------------------"); UserInfo userInfo = userInfoList.parallelStream().findAny().orElse(null); System.out.println(userInfo); } 5.map/peek

场景: Stream里面的每个元素都要执行一样的功能的时候 。 //将stream里面的每个数据转换成另外一个类型的数据。

private static void demo6() { List<UserInfo> userInfoList = new ArrayList<>(10); Collections.addAll(userInfoList, new UserInfo(1, "jim", 20), new UserInfo(2, "tom", 18), new UserInfo(3, "lilei", 23), new UserInfo(4, "hanmeimei", 16) ); //将集合里面每个用户的name的数据全部转换成大写字母 for (UserInfo userInfo : userInfoList) { userInfo.setName(userInfo.getName().toUpperCase()); } //获得集合里面每个用户对象的name的属性数据 全部转大写字母存储 List<String> collect = userInfoList.parallelStream().map(new Function<UserInfo, String>() { @Override public String apply(UserInfo userInfo) { return userInfo.getName().toUpperCase(); } }).collect(Collectors.toList()); List<String> collect = userInfoList.parallelStream() .map(userInfo -> userInfo.getName().toUpperCase()).collect(Collectors.toList()); collect.forEach(System.out::println); System.out.println("-----------------------------"); userInfoList.forEach(System.out::println); } private static void demo7() { List<UserInfo> userInfoList = new ArrayList<>(10); Collections.addAll(userInfoList, new UserInfo(1, "jim", 20), new UserInfo(2, "tom", 18), new UserInfo(3, "lilei", 23), new UserInfo(4, "hanmeimei", 16) ); List<UserInfo> collect = userInfoList.stream().map(new Function<UserInfo, UserInfo>() { @Override public UserInfo apply(UserInfo userInfo) { userInfo.setName(userInfo.getName().toUpperCase()); return userInfo; } }).collect(Collectors.toList()); /* List<UserInfo> collect = userInfoList.stream().map(userInfo -> { userInfo.setName(userInfo.getName().toUpperCase()); return userInfo; }).collect(Collectors.toList());*/ //前提: 对Stream的元素都执行同样的功能 最后集合里面的元素类型与原集合数据类型一致 建议使用peek替换map List<UserInfo> collect = userInfoList.parallelStream() .peek(userInfo -> userInfo.setName(userInfo.getName().toUpperCase())).collect(Collectors.toList()); System.out.println(collect); System.out.println(userInfoList); } 6.flatMap private static void demo8() { List<Integer> list1 = List.of(1, 2, 30, 4, 5); List<Integer> list2 = List.of(10, 27, 3, 40, 5); List<Integer> list3 = List.of(11, 2, 3, 4, 5); List<Integer> list4 = List.of(100, 21, 3, 4, 50); //获得前5个数据(降序)+去重 //核心: 将多个集合数据转换到一个集合中. List<Integer> collect = Stream.of(list1, list2, list3, list4).flatMap(List::stream) .distinct().sorted(Comparator.reverseOrder()).limit(5).collect(Collectors.toList()); System.out.println(collect); /*Stream.of(list1, list2, list3, list4).flatMapToInt(new Function<List<Integer>, IntStream>() { @Override public IntStream apply(List<Integer> list) { return list.stream().mapToInt(Integer::intValue); } })*/ Stream.of(list1, list2, list3, list4) .flatMapToInt(list -> list.stream().mapToInt(Integer::intValue)) .distinct().sorted().limit(5).forEach(System.out::println); } 7.reduce private static void demo9() { List<Integer> list = List.of(89, 90, 98); int sum = 0; for (Integer integer : list) { sum+=integer; } Integer sum1 = list.stream().reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer num1, Integer num2) { //System.out.println(num1+":"+num2); return num1 + num2; } }).orElse(null); Integer sum1 = list.stream().reduce(Integer::max).orElse(null); System.out.println(sum1); }
标签:

了解Java集合的概念和体系:Collection<T>、Collections与Stream的使用由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“了解Java集合的概念和体系:Collection<T>、Collections与Stream的使用