Stream
Stream流其实就是一个集合元素的函数模型,他并不是集合,也不是数据结构,其本身并不存储任何的元素或地址(JDK8之后新增的功能)
使用流的步骤:
当我们使用一个流的时候,通常包括三个步骤:
1.获取一个数据源
2.执行操作获取想要的结果
3.每次操作,原有的流对象不改变,返回一个新的Stream对象
Stream的特性:
1.Stream不会储存数据,一般会输出结果
2.Stream不会改变数据源,通常情况下会生成一个新的集合
3.Stream具有延迟执行的特性,只有调用终端操作时,中间操作才会执行。
相关使用:
List<String> list = Arrays.asList("a","b","c");
Arrays.asList是将数组转化成List集合的方法
ps:
1.该方法适用于对象型数据的数组(String、Integer...)
2.该方法不建议使用于基本数据类型的数组(byte,short,int,long,float,double,boolean)
3.该方法将数组与List列表链接起来:当更新其一个时,另一个自动更新
4.不支持add()、remove()、clear()等方法
用此方法得到的List的长度是不可改变的
创建一个顺序流:
Stream<String> stream = list.stream();
创建一个并行流:
Stream<String> parallelStream = list.parallelStream();
创建个字符串流:Stream.of();
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);
Stream iterate(final T seed ,final UnaryOperator f):
指定一个seed常量,生成从seed到常量f(由UnaryOperator返回的值得到)的流。
public static void main(String[] args) {
Stream.iterate(0, n -> n + 1).limit(5).forEach(a -> {
System.out.println(a);
});
}
根据起始值seed(0),每次生成一个指定递增值(n+1)的数,limit(5)用于截断流的长度,即只获取前5个元素。
forEach():看起来和咱们增强for循环一样,实际上大概的功能也是这样:打印集合元素:
.forEach(System.out::println);// 双冒号语法,方法引用
.findFirst()找到第一个元素
.findAny();随便找一个
判断有没有任意一个人大于50岁:(任意匹配)
boolean b = personList.stream().anyMatch(item -> item.getAge() > 35);
判断是不是所有人都大于50岁:
b = personList.stream().allMatch(item -> item.getAge() > 35);
收集元素:(三个集合):
List<Integer> collect = simpleList.stream().collect(Collectors.toList());
Set<Integer> collect1 = simpleList.stream().collect(Collectors.toSet());
Map<Integer, Integer> map = simpleList.stream()
.collect(Collectors
.toMap(item -> item, item -> item + 1));
统计:
long count = new Random().ints().limit(50).count();//获取长度
System.out.println(count);
OptionalDouble average = new Random().ints().limit(50).average();//获取五十个的平均数
average.ifPresent(System.out::println);
int sum = new Random().ints().limit(50).sum();//获取五十个随机数的和
System.out.println(sum);
规约(reduce)缩减,把一个流缩减成一个值
可以实现对集合的求和,求乘积,求最值
Integer result = simpleList.stream().reduce(1, (n1, n2) -> n1 - n2);
System.out.println(result);
.collect(Collectors.joining("-"));---字符串拼接用-拼接。
List<String> list = Arrays.asList("A","B","C");
String string = list.stream().collect(Collectors.joining("-"));
System.out.println("拼接后的字符串:" + string);
按照某一条件分组(分组将集合分为多个map)
// 根据工资分组
Map<Boolean, List<Person>> collect = personList.stream().collect(Collectors.groupingBy(x -> x.getSalary() > 5000));
System.out.println(collect);
// 根据性别分组
Map<String, List<Person>> collect1 = personList.stream().collect(Collectors.groupingBy(Person::getGender));
System.out.println(collect1);
// 将员工根据性别分组,再按地区分组
Map<String, Map<String, List<Person>>> collect2 = personList.stream()
.collect(Collectors.groupingBy(Person::getGender, Collectors.groupingBy(Person::getArea)));
System.out.println(collect2);
筛选:
// 筛选员工中工资大于8000的人,并形成新的集合
List<Person> collect = personList
.stream()
.filter(item -> item.getSalary() > 5000)
.collect(Collectors.toList());
System.out.println(collect);
映射:(将一个流的元素按照一定映射规则映射到另一个流中):
// 将员工的工资全部增加1000
// personList
// .stream().map(item -> {
// item.setSalary(item.getSalary() + 1000);
// return item;
// }).forEach(System.out::println);
List<StringBuilder> collect = simpleList.stream().map(item -> {
StringBuilder strb = new StringBuilder();
strb.append(item);
return strb;
}).collect(Collectors.toList());
System.out.println(collect);
排序:sorted:
// 将员工按工资由低到高排序(自然排序--升序)
List<String> collect = personList.stream()
.sorted(Comparator.comparing(Person::getSalary))
.map(Person::getName)
.collect(Collectors.toList());
System.out.println(collect);
// 按照员工工资的降序
List<String> collect1 = personList
.stream()
.sorted(Comparator.comparing(Person::getSalary).reversed())
.map(Person::getName)
.collect(Collectors.toList());
System.out.println(collect1);
peek操作:调试:
// 在stream中调试,stream不支持debug
List<Person> collect = personList.stream()
.filter(item -> item.getSalary() > 5000)
.peek(System.out::println)
.collect(Collectors.toList());
System.out.println(collect);
其他操作:合并、去重、限制、跳过。。。。
/*
distinct:去重
skip:跳过几个数据
limit:限制使用几个数据
*/
simpleList
.stream()
.distinct()
.skip(2)
.limit(6)
.forEach(System.out::println);