目录
判断(anyMatch/allMatch/noneMatch)
转特殊流(mapToInt/mapToDouble/mapToLong/flatMapToDouble/flatMapToInt/flatMapToLong)
3.分组(partitioningBy/groupingBy)(groupingBy不太理解,以后有时间可以去研究研究)
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据 ,循环往下处理,最后得出结果。
什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似于jquery的处理方式。也有点类似于thinkphp的处理。
Stream的创建
1.集合创建(List)
//List<Integer> interList = Arrays.asList(1, 2);
List<Integer> interList = new ArrayList<>();
interList.add(1);
interList.add(2);
//顺序流
Stream<Integer> stream = interList.stream();
stream.forEach(System.out::println);
//顺序流转并行流
Stream<Integer> parallelStream2 = stream.parallel();
//并行流
Stream<Integer> parallelStream = interList.parallelStream();
parallelStream.forEach(System.out::println);
//并行流转顺序流
Stream<Integer> stream2 =parallelStream.sequential();
2. 数组创建
Integer[] aa = {5,4,3,2,1};
//默认所有数据写入流
//Stream<Integer> IntergerStream = Arrays.stream(aa);
//可以部分写入流
Stream<Integer> IntergerStream = Arrays.stream(aa,1,aa.length);
//java 基本数据类型数组创建流(其他类型包含double、long创建流(部分创建流))
int[] intList = {5,4,3,2,1};
IntStream intStream = Arrays.stream(intList);
3.静态方法创建
/**
* 源码如下,使用很方便
* public static<T> Stream<T> of(T... values) {
* return Arrays.stream(values);
* }
*/
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
//返回有序无限连续 Stream由函数的迭代应用产生 f至初始元素 seed ,产生 Stream包括 seed , f(seed) , f(f(seed)) ,等
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
//返回无限顺序无序流,其中每个元素由提供的 Supplier 。
Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);
//返回一个空的顺序 Stream
Stream<Integer> stream4 = Stream.empty();
Stream方法
循环(forEach)
可用于迭代流中的每一个元素
List<String> list = new ArrayList<>();
list.add("好");
list.add("好的");
list.stream().forEach(System.out::println)
循环打印每一个元素
排重(distinct)
通过流中元素的 hashCode() 和 equals() 去除重复元素(牛B)
List<String> list = new ArrayList<>();
list.add("好");
list.add("好");
list.stream().distinct().forEach(System.out::println);
限制(limit)
获取指定数量的流
List<String> list = new ArrayList<>();
list.add("好");
list.add("好");
list.stream().limit(1).forEach(System.out::println);
排序 (sorted)
对流进行排序,一下三条排序方法等价。
List<Student> list = new ArrayList<>();
list.add(new Student(5,"风"));
list.add(new Student(4,"风"));
list.add(new Student(9,"风"));
list.add(new Student(8,"风"));
list.add(new Student(20,"风"));
list.stream().sorted((x,y)->x.getId()-y.getId()).forEach(System.out::println);
list.stream().sorted(Comparator.comparing(Student::getId)).forEach(System.out::println);
list.stream().sorted(Comparator.comparing(student -> student.getId())).forEach(item->System.out.println(item));
public static class Student{
public Integer id;
public String name;
public Student(Integer id,String name){
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
筛选(filter)
通过筛选过滤掉不必须要元素
List<String> list = new ArrayList<>();
list.add("真");
list.add("的");
list.add("好");
list.stream().filter(item->item.equals("好")).forEach(System.out::println);
聚合(count/min/max)
和mysql的操作差不多。max、min与sored入参一致。
//统计数量
Stream<Integer> streamList = Stream.of(1,4,5,3,7);
System.out.println(streamList.count());
//最大值1(最小值同理)
Stream<Integer> streamList2 = Stream.of(1,4,5,3,7);
//Optional<Integer> max = streamList2.max((x,y)->x-y);
Optional<Integer> max = streamList2.max(Integer::compareTo);
System.out.println(max.get());
//最大值 例2
Stream<String> streamList3 = Stream.of("adnm", "admmt", "pot", "xbangd", "weoujgsd");
//Optional<String> max1 = streamList3.max((x,y)->x.length()-y.length());
//Optional<String> max1 = streamList3.max(String::compareTo);
//Optional<String> max1 = streamList3.max(String::compareTo);
//Optional<String> max1 = streamList3.max(Comparator.comparing(String::length));
Optional<String> max1 = streamList3.max(Comparator.comparingInt(String::length));
System.out.println(max1.get());
匹配(findFirst/findAny)
返回第一个值
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
// 匹配第一个
Optional<Integer> findFirst = list.stream().findFirst();
// 匹配任意(适用于并行流)
Optional<Integer> findAny = list.parallelStream().findAny();
System.out.println("匹配第一个值:" + findFirst.get());
System.out.println("匹配任意一个值:" + findAny.get());//此方法有且只有并行流返回的结果可能不一致。
判断(anyMatch/allMatch/noneMatch)
根据条件判断流是否存在
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
// 是否包含符合特定条件的元素
boolean anyMatch = list.stream().anyMatch(x -> x < 6);
System.out.println("是否存在小于6的值:" + anyMatch);
// 是否包含符合条件的所有元素
boolean anyMatch = list.stream().allMatch(x -> x < 6);
System.out.println("是否所有流都小于6:" + anyMatch);
// 是否包含符合条件的所有元素
boolean anyMatch = list.stream().noneMatch(x -> x < 6);
System.out.println("是否所有流都不存在小于6:" + anyMatch);
映射(map/flatMap)
map
:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。flatMap
:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
list.stream().map(i -> i+1).forEach(System.out::println);
//将两个流合一个流
List<String> list2 = Arrays.asList("m,k,l,a", "1,3,5,7");
list2.stream().flatMap(s -> {
// 将每个元素转换成一个stream
String[] split = s.split(",");
Stream<String> s2 = Arrays.stream(split);
return s2;
}).forEach(System.out::println);
转特殊流(mapToInt/mapToDouble/mapToLong/flatMapToDouble/flatMapToInt/flatMapToLong)
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
IntStream intStream = list.stream().mapToInt(i -> i+1);
收集器(collect)
1.归集(toList/toSet/toMap)
List<Integer> list = Arrays.asList(6, 6, 9, 3, 8, 2, 1);
List<Integer> newList = list.stream().map(i->i+1).collect(Collectors.toList());
Map<String, BigDecimal> maps = list.stream().distinct().collect(Collectors.toMap(i->i.toString(), i->new BigDecimal(0)));
Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName, p -> p));
2.统计(count/averaging)
- 计数:counting
- 平均值:averagingInt、averagingLong、averagingDouble
- 最值:maxBy、minBy
- 求和:summingInt、summingLong、summingDouble
- 统计以上所有:summarizingInt、summarizingLong、summarizingDouble
List<Integer> list = Arrays.asList(6, 6, 6, 6, 6,6,6);
//流数量
System.out.println(list.stream().collect(Collectors.counting()));
//平均数
System.out.println(list.stream().collect(Collectors.averagingInt(i->i)));
//最大值
System.out.println(list.stream().collect(Collectors.maxBy(Integer::compareTo)).get());
//求和
System.out.println(list.stream().collect(Collectors.summingInt(i->i)));
//统计以上所有
System.out.println(list.stream().collect(Collectors.summarizingDouble(i->i)));
3.分组(partitioningBy/groupingBy)(groupingBy不太理解,以后有时间可以去研究研究)
/**
* Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
* return partitioningBy(predicate, toList());
* }
* 可以看出函数的参数一个Predicate接口,那么这个接口的返回值是boolean类型的,也只能是boolean类型,然后他的返回值是Map的key是boolean类型,也就是这个函数的返回值只能将数据分为两组也就是ture和false两组数据。
*/
Map<Boolean, List<Integer>> part = Stream.iterate(0,i->i+1).limit(10).collect(Collectors.partitioningBy(x -> x>4));
System.out.println(part);
4.接合(joining)
这个方法,相当好用,list转String使用比较方便
List<Integer> list = Arrays.asList(6, 6, 6, 6, 6,6,6);
String listStr = list.stream().map(i->String.valueOf(i)).collect(Collectors.joining("-"));
5.归约(reducing)
//与下面规约类似,但是此处能多传参数,更加灵活
Integer sum = Stream.iterate(0,i->i+1).limit(5).collect(Collectors.reducing(0, i->i, (i, j) -> (i + j - 5000)));
归约(reduce)
//如果2位参数,第一位是默认值,可以直接返回基础类型/封装类型
//1位参数,返回Optional<Object>对象
int sum = Stream.of(0,9,8,4,5,6,-1).reduce(0,(e1,e2)->e1+e2);
Optional<Integer> sum2 = Stream.of(0,9,8,4,5,6,-1).reduce(Integer::sum);
//最大值(最小值同理)
System.out.println(Stream.of(0,9,8,4,5,6,-1).reduce(Integer::max).get());
System.out.println(Stream.of(0,9,8,4,5,6,-1).reduce((x,y)->x>y?x:y).get());
合并(concat)
Stream<String> stream1 = Stream.of( "b", "c", "d");
Stream<String> stream2 = Stream.of("d", "e", "f", "g" );
// concat:合并两个流 distinct:去重
List<String> newList = Stream.concat(stream1, stream2).collect(Collectors.toList());
跳跃(skip)
在丢弃流的第一个 n
元素后,返回由该流的 n
元素组成的流。可配合limit进行分页。
// skip:跳过前1个数据
List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
返回数组(toArray)
流转化成为数组
//流转数组
Object[] is = Stream.iterate(0,i->i+1).limit(10).toArray();
String str = Arrays.toString(is);
System.out.println(str);
Integer[] is2 = Stream.iterate(0,i->i+1).limit(10).toArray(Integer[]::new);
用于调试的(peek)
不能单纯看做map的无返回值方法,用于打印调试流即可。
Stream.of(1,6,8,6,7,8).peek(System.out::println)