最近编码的时候用到了Stream这个东西,以前也用过,但是对它没有一个系统的认知。在好奇心的驱动下还是决定花一些时间去系统地学一学。下面是我看了B站视频(黑马)后的总结,不了解Stream的掘友可以看看本文,节省大家再去看视频的时间。
一、创建不可变的集合
不可变的集合,顾名思义,就是不想让别人修改集合中的内容,也无法修改。如何创建呢?
(一)创建格式
在List、Set、Map接口中,都存在静态的of方法,可以获取一个不可变的集合:
- static List of(E...elements) 创建一个具有指定元素的List集合对象。
- static Set of(E...elements) 创建一个具有指定元素的Set集合对象。
- static Map of(E...elements) 创建一个具有指定元素的Map集合对象。
(List.of在jdk8中没有,需要jdk9及以上的版本。)
public static void main(String[] args) {
List list = List.of("张三","李四","王五");
for(String tmp : list){
System.out.println(tmp);
}
System.out.println("----------------------------");
Set set = Set.of(1,2,3,4);
for(int x : set){
System.out.println(x);
}
System.out.println("-----------------------------");
Map map = Map.of("王五", 1, "李四", 2);
Set entries = map.entrySet();
for(Map.Entry entry : entries){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
System.out.println("------------------------------");
}
- 这些集合不能添加,不能删除,不能修改,如果修改会抛异常:
public static void main(String[] args) {
List list = List.of("张三","李四","王五");
list.remove(0);
}
结果:
- 这里的Set集合中不能有相同的值,Map不能有相同的key,否则抛异常。
public static void main(String[] args) {
Set set = Set.of(1,1,2,3,4);
}
Map.of()
里的参数最多传 10 个键值对,源码里of()方法参数最多的也就10对。
那为什么不用可变参数呢?因为可变参数只能有一个,并且要在参数列表的末尾。如果想要存超过10个的键值对,我们可以利用数组->可变参数
:
public static void main(String[] args) {
Map map = new HashMap();
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
map.put(4,"d");
map.put(5,"e");
map.put(6,"f");
map.put(7,"g");
map.put(8,"h");
map.put(9,"i");
map.put(10,"j");
map.put(11,"k");
map.put(12,"l");
//获取所有的键值对
Set entries = map.entrySet();
//把entries变成一个数组
//如果集合的长度 〉数组的长度﹔数据在数组中放不下,此时会根据实际数据的个数,重新创建数组
//如果集合的长度〈=数组的长度:数据在数组中放的下,此时不会创建新的数组,而是直接用原来的数组
Map.Entry[] array = entries.toArray(new Map.Entry[0]);
//生成不可变map集合,ofEntries()的参数是可变参数,可变参数可以使用数组。
Map map1 = Map.ofEntries(array);
}
第二种方式,但是要jdk10及以上:
public static void main(String[] args) {
Map map = new HashMap();
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
map.put(4,"d");
map.put(5,"e");
map.put(6,"f");
map.put(7,"g");
map.put(8,"h");
map.put(9,"i");
map.put(10,"j");
map.put(11,"k");
map.put(12,"l");
//生成不可变集合
Map map1 = Map.copyOf(map);
}
(二)不可变集合的作用
- 保证线程安全:不可变集合是一种在创建之后就不再变更的对象,这种特性使得它们天生支持线程安全。
- 防止数据被篡改:不可变集合可以用于封装一些敏感或重要的数据,防止它们被外部程序或不可信的库修改或破坏。
二、Stream 流
(一)Stream 的思想
Stream 为什么叫流?可以通过下面的案例来引入这个概念。
public static void main(String[] args) {
List list = new ArrayList();
list.add("陈大帅");
list.add("陈小帅");
list.add("小红");
list.add("李四");
list.add("陈四");
//筛选姓陈的,并且名字是3个字的人
list.stream().filter(name->name.startsWith("陈"))
.filter(name->name.length()==3)
.forEach(name-> System.out.println(name));
}
Stream 就像流水线一样,这个流水线第一道工序就是过滤掉不姓陈的,第二道工序过滤掉字的数量不等于3的,最后的工序就是打印。
(二)Stream流的使用步骤
1.把数据放到流水线上
获取方式 | 方法名 | 说明 |
---|---|---|
单列集合 | default Stream stream() | collection中的默认方法(由于单列集合实现了Collection接口,可以直接.stream()) |
双列集合(Map等) | 无 | 无法直接使用stream流 |
数组 | public static Stream stream(T[] array) | Arrays工具类中的静态方法 |
零碎数据 | public static Stream stream(T[] array) | Stream接口中的静态方法 |
public static void main(String[] args) {
//1.单列集合
List list = new ArrayList();
Collections.addAll(list,"a","b","b","b","c","d","e");//添加数据
list.stream().forEach(s -> System.out.println(s));//流水线操作
//2.双列集合
Map map = new HashMap();
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
map.put(4,"d");
map.put(5,"e");
map.put(6,"f");
map.keySet().stream().forEach(s-> System.out.println(s));//方式1:获取key的流水线,利用key与value的关系来操作整体
map.entrySet().stream().forEach(entry-> System.out.println(entry));//方式2:获取键值对的流水线
//3.数组
int[] arr = {1,2,3,4,5,6,7,8};
Arrays.stream(arr).forEach(x-> System.out.println(x));//利用 Arrays 工具类来获取流
String[] strs = {"a","b","c"};
Arrays.stream(strs).forEach(str-> System.out.println(str));
//4.零散的数据
Stream.of("a","b","c","d","e").forEach(x-> System.out.println(x));//利用 Stream 来获取
}
2.中间方法
Stream方法 | 中文解释 | 作用 |
---|---|---|
Stream filter(Predicate
|