Java#31(不可变集合,Stream流和方法引用)
创始人
2024-03-15 16:27:56
0次

目录

一.创建不可变集合: 不可以被修改的集合

1.List接口创建不可变集合

2.Set接口创建不可变集合

3.Map接口创建不可变集合

二.Stream流

1.如何获取Stream流?

2.Stream流的中间方法

3.Stream流终结方法

三.方法引用

1.引用静态方法

2.引用成员方法

3.引用结构方法

4.使用类名引用成员方法

5.引用数组的构造方法


一.创建不可变集合: 不可以被修改的集合

作用: 不让别人修改集合中的内容

1.List接口创建不可变集合

格式: List.of(数据); 

可以进行查询和遍历但是不能修改内容

代码示范:

package Demo;import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;public class Test1 {public static void main(String[] args) {List list = List.of("张三", "李四", "王五");System.out.println(list.get(0));System.out.println(list.get(1));System.out.println(list.get(2));System.out.println("-----------------------");//遍历for (String s : list) {System.out.println(s);}System.out.println("------------------------");list.forEach(s-> System.out.println(s));list.add("maliu");}
}

 (未对集合内容进行更改)

 (想修改集合内容就会报错)

2.Set接口创建不可变集合

格式: Set.of(数据);

可以进行查询和遍历但是不能修改内容(元素不能出现重复)

3.Map接口创建不可变集合

可以进行查询和遍历但是不能修改内容(元素不能出现重复)

格式: Map.of(数据); (键值对数量最多是10个)

         Map.copyOf(Map集合); (没有键值对数量限制, 在JDK10开始出现)

(Map.of()添加10个键值对,没有报错) 

 (Map.of()添加11个键值对,直接报错) 

Map.copyOf(Map集合); 的代码示范:

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;public class Test3 {public static void main(String[] args) {Map map1 = new HashMap();map1.put("1","a");map1.put("2","a");map1.put("3","a");map1.put("4","a");map1.put("5","a");map1.put("6","a");map1.put("7","a");map1.put("8","a");map1.put("9","a");map1.put("10","a");map1.put("11","a");map1.put("12","a");Map map2 = Map.copyOf(map1);map2.forEach((s, s2)-> System.out.println(s+"="+s2));//map2.put("13","a");}
}

结果展示: 

二.Stream流

作用: 结合了lambda表达式,简化集合,数组的操作

步骤:

(1)先得到一条Stream流,并把数据放上去

(2)利用Stream流中的API进行各种操作(过滤,转换(中间方法: 方法调用后还可以调用其他方法), 统计, 打印(终结方法: 最后一步, 调用完毕之后, 不能调用其他方法))

1.如何获取Stream流?

获取方式                                        方法名                                                       说明
单列集合                       default Stream stream0                      Collection中的默认方法
双列集合                                            无                                          无法直接使用stream流
数组              public static Stream stream(T[ ] array)  Arrays工具类中的静态方法
一堆零散数据      public static Stream of(T... values)       stream接口中的静态方法

单列集合获取Stream流代码示范:

import java.util.ArrayList;
import java.util.Collections;public class StreamDemo1 {public static void main(String[] args) {ArrayList arr = new ArrayList<>();Collections.addAll(arr,"b","c","a");arr.stream().forEach(s -> System.out.println(s));//遍历集合}
}

结果展示:

 双列集合获取Stream流代码示范:

import java.util.HashMap;public class StreamDemo2 {public static void main(String[] args) {HashMap map = new HashMap<>();map.put("a",1);map.put("b",2);map.put("c",3);//第一种方式map.keySet().forEach(s -> System.out.println(s));System.out.println("---------------------------");//第二种方式map.entrySet().forEach(a-> System.out.println(a));}
}

结果展示:

数组获取Stream流代码示范:

import java.util.Arrays;public class StreamDemo3 {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7};Arrays.stream(arr).forEach(i-> System.out.println(i));}
}

结果展示:

 一堆零散数据获取Stream流代码示范:

import java.util.stream.Stream;public class StreamDemo4 {public static void main(String[] args) {Stream.of(1,2,3,4,5).forEach(i-> System.out.print(i+" "));System.out.println();System.out.println("-----------------");Stream.of("a","b","c").forEach(s-> System.out.print(s+" "));String[] s = {"a","b","c","d"};Stream.of(s).forEach(a-> System.out.print(a+" "));System.out.println();int[] arr1 = {1,2,3,4,5,6};Stream.of(arr1).forEach(i-> System.out.print(i+" "));}
}

结果展示:

注意: Stream.of()   ()中添加元素是类型要相同, 添加数组时只能添加引用数据类型,如果添加基本数据类型打印的是地址

2.Stream流的中间方法

                     名称                                                                       说明
Stream filter(Predicate predicate)                过滤
Stream limit(long maxSize)                                       获取前几个元素
Stream skip(long n)                                                   跳过前几个元素
Stream distinct()                                    元素去重,依赖(hashCode和equals方法)
static Stream concat(Stream a, Stream b)    合并a和b两个流为一个流

Stream map(Function mapper)                    转换流中的数据类型
注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,所以没有必要创建一个新的变量来存储, 建议使用链式编程

注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据

代码示范:

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;public class StreamDemo5 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,"小明","小红","小李飞刀","小张","刘备","马超","黄忠");//1.filterlist.stream()./*filter(new Predicate() {@Overridepublic boolean test(String s) {return s.startsWith("小");}})*/filter(s-> s.startsWith("小"))//true表示留下, false表示舍弃.forEach(s-> System.out.println(s));System.out.println("======================");//2.limitlist.stream().limit(3).forEach(s-> System.out.println(s));System.out.println("======================");//3.skiplist.stream().skip(2).forEach(s -> System.out.println(s));System.out.println("======================");//4.distinctArrayList list2 = new ArrayList<>();Collections.addAll(list2,"李华","王五");Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s));System.out.println("======================");//5.mapArrayList list3 = new ArrayList<>();Collections.addAll(list3,"小华-12","小五-13","马六-14");//第一个是原本的数据类型,//第二个要转化成的数据类型list3.stream()
/*                .map(new Function() {@Overridepublic Integer apply(String s) {String[] str = s.split("-");String ageString = str[1];int age = Integer.parseInt(ageString);return age;}})*/.map(s->Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));}
}

3.Stream流终结方法

          名称                                                    说明
void forEach(Consumer action)                遍历
long count()                                                 统计
toArray()                                       收集流中的数据,放到数组中
collect(Collector collector)         收集流中的数据,放到集合中

前三个方法的代码示范: 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;public class Test1 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,"asd","zxc","qwe");//1.forEach(Consumer action)list.stream().forEach(s -> System.out.println(s));//2.count()long count1 = list.stream().count();System.out.println(count1);//3.toArray()//转化成什么类型的数组String[] str = list.stream().toArray(new IntFunction() {@Overridepublic String[] apply(int value) {return new String[value];}});System.out.println(Arrays.toString(str));//简化写法String[] str1 = list.stream().toArray(value -> new String[value]);System.out.println(Arrays.toString(str));}
}

结果展示: 

三.方法引用

1.引用方法必须是函数式接口

2.被引用的方法必须已经存在

3.被引用方法的形参和返回值需要和抽象方法保持一致

4.被引用的方法的功能要满足当前需求

5. :: 是方法引用符

代码示范:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;public class Test1 {public static void main(String[] args) {Integer[] arr = {1,4,7,2,6,3,5};//将数组从大到小排序//1.匿名内部类/* Arrays.sort(arr, new Comparator() {@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}});*///2.lambda表达式/*Arrays.sort(arr,(o1, o2)-> o2-o1);*///3.方法引用//::方法引用符Arrays.sort(arr,Test1::subtraction);System.out.println(Arrays.toString(arr));}public static int subtraction(int num1,int num2){return num2-num1;}
}

结果展示:

 1.引用静态方法

格式: 类名::静态方法

例如: Integer::parseInt

代码示范: 

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;public class Test2 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,"1","2","3","4","5");/*list.stream().map(new Function() {@Overridepublic Integer apply(String s) {Integer i = Integer.parseInt(s);return i;}}).forEach(s-> System.out.println(s));*/list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));}
}

结果展示: 

2.引用成员方法

格式:  对象::成员方法

(1)其他类: 其他类对象::方法名

(2)本类: this::方法名  (引用处不能是静态方法)

(3)父类: super::方法名 (引用处不能是静态方法)

代码示范: 第一个是类的代码,第二个是测试代码

public class Demo1 {public static boolean stringJudge(String s){return s.startsWith("小")&&s.length()==2;}}
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;public class Test3 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,"小明","小红","小张","小李飞刀","张三","李四");//普通list.stream().filter(new Predicate() {@Overridepublic boolean test(String s) {return s.startsWith("小")&&s.length()==2;}}).forEach(s-> System.out.println(s));System.out.println("=========================");//简化list.stream().filter(s->s.startsWith("小")&&s.length()==2).forEach(s-> System.out.println(s));System.out.println("=========================");//方法引用list.stream().filter(Demo1::stringJudge).forEach(s-> System.out.println(s));}
}

结果展示: 

3.引用结构方法

格式: 类名::new

例如: Student::new

代码示范: 第一个是Student类的代码,第二个是测试类的代码

public class Student {private String name;private int age;public Student() {}//str是stream流中的数据public Student(String str) {String[] arr = str.split(",");this.name = arr[0];this.age = Integer.parseInt(arr[1]);}public Student(String name, int aeg) {this.name = name;this.age = aeg;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return aeg*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", aeg = " + age + "}";}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;public class Test4 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,"小明,18","小红,19","小张,20","小李飞刀,21","张三,22","李四,23");//封装成Student对象并收集到List集合中//普通方法List newList = list.stream().map(new Function() {@Overridepublic Student apply(String s) {String[] arr = s.split(",");String name = arr[0];int age = Integer.parseInt(arr[1]);return new Student(name, age);}}).collect(Collectors.toList());System.out.println(newList);System.out.println("==========================");//引用构造方法List newList2 = list.stream().map(Student::new).collect(Collectors.toList());System.out.println(newList2);}
}

结果展示: 

 4.使用类名引用成员方法

格式: 类名::成员方法

例如: String::substring

注意: 被引用的方法形参是跟抽象方法第二个参数后面的保持一致

代码示范: 

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;public class Test5 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,"aaa","bbb","ccc");//把数据变成大写然后遍历//普通list.stream().map(new Function() {@Overridepublic String apply(String s) {return s.toUpperCase();}}).forEach(s-> System.out.println(s));System.out.println("==========================");//引用方法list.stream().map(String::toUpperCase).forEach(s-> System.out.println(s));}
}

结果展示: 

5.引用数组的构造方法

格式: 数据类型[ ]::new

例如: Integer::new

注意: 数组的类型,需要跟流中数组的类型保持一致

代码示范: 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;public class Test6 {public static void main(String[] args) {ArrayList list = new ArrayList<>();Collections.addAll(list,1,2,3,4,5,6);//普通写法Integer[] arr1 = list.stream().toArray(new IntFunction() {@Overridepublic Integer[] apply(int value) {return new Integer[value];}});//引用方法Integer[] arr2 = list.stream().toArray(Integer[]::new);System.out.println(Arrays.toString(arr1));System.out.println("===================");System.out.println(Arrays.toString(arr2));}
}

结果示范: 

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...