Java进阶,不可变集合,Stream流
一.不可变集合
-
不可变集合,就是不可被修改的集合。
-
集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变。否则报错。
-
如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。
-
或者当集合对象被不可信的库调用时,不可变形式是安全的。
如何创建不可变集合?
- 在List、Set、Map接口中,都存在of方法,可以创建一个不可变的集合。
方法名称 | 说明 |
---|---|
static List of(E…elements) | 创建一个具有指定元素的List集合对象 |
static Set of(E…elements) | 创建一个具有指定元素的Set集合对象 |
static <K , V> Map<K,V> of(E…elements) | 创建一个具有指定元素的Map集合对象 |
-
这个集合不能添加,不能删除,不能修改。
-
public class Demo { public static void main(String[] args) { //1.不可变的List集合 List<Double> lists = List.of(569.0, 314.4, 456.3); //lists.add(434.4);报错 //lists.set(2,311.1);报错 double score = lists.get(0); System.out.println(score); //2.不可变的Set集合 Set<String> names = Set.of("刘备", "关羽", "张飞", "卧龙", "凤雏"); //names.add("大小姐");报错 System.out.println(names); //3.不可变的Map Map<String, Integer> maps = Map.of("华为",2,"小米",3,"苹果",4); //maps.put("vivo",2);报错 System.out.println(maps); } }
二.Stream流
1.Stream流的概述
- 在Java 8中,得益于Lambda所带来的函数式编程, 引入了一个全新的Stream流概念。
- 目的:用于简化集合和数组操作的API。
Stream流式思想的核心:
1.先得到集合或者数组的Stream流(就是一根传送带)
2.把元素放上去
3.然后就用这个Stream流简化的API来方便的操作元素。
2.Stream流的获取
Stream操作集合或者数组的第一步是先得到Stream流,然后才能使用流的功能。
集合获取Stream流的方式
- 可以使用Collection接口中的默认方法stream()生成流
名称 | 说明 |
---|---|
default Stream stream() | 获取当前集合对象的Stream流 |
数组获取Stream流的方式
名称 | 说明 |
---|---|
public static Stream stream(T[] array) | 获取当前数组的Stream流 |
public static Stream of(T… values) | 获取当前数组/可变数据的Stream流 |
public class StreamDemo {
public static void main(String[] args) {
//Collection集合获取流
Collection<String> list = new ArrayList<>();
Stream<String> s = list.stream();
//Map集合获取流
Map<String, Integer> maps = new HashMap<>();
//键流
Stream<String> keyStream = maps.keySet().stream();
//值流
Stream<Integer> valueStream = maps.values().stream();
//键值对流(拿整体)
Stream<Map.Entry<String,Integer>> keyAndvalueStream = maps.entrySet().stream();
//数组获取流
String[] names = {
"刘备","关羽","张飞","卧龙"};
Stream<String> nameStream = Arrays.stream(names);
Stream<String> nameStream1 = Stream.of(names);
}
}
Stream流的三类方法
获取Stream流
- 创建一条流水线,并把数据放到流水线上准备进行操作
中间方法
- 流水线上的操作。一次操作完毕之后,还可以继续进行其他操作。
终结方法
- 一个Stream流只能有一个终结方法,是流水线上的最后一个操作
3.Stream流常用API
Stream流的常用API(中间操作方法)
名称 | 说明 |
---|---|
Stream filter(Predicate<? super T> predicate) | 用于对流中的数据进行过滤。 |
Stream limit(long maxSize) | 获取前几个元素 |
Stream skip(long n) | 跳过前几个元素 |
Stream distinct() | 去除流中重复的元素。依赖(hashCode和equals方法) |
static Stream concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
注意:
- 中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程。
- 在Stream流中无法直接修改集合、数组中的数据。
Stream流的常见终结操作方法
名称 | 说明 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行遍历操作 |
long count() | 返回此流中的元素数 |
注意:终结操作方法,调用完成后流就无法继续使用了,原因是不会返回Stream了。
public class StreamDemo1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌","周芷若","赵敏",