Java 8 Stream

目录

什么是 Stream?

Stream的创建

 Stream方法

循环(forEach)

排重(distinct)

限制(limit)

排序 (sorted)

筛选(filter)

聚合(count/min/max)

匹配(findFirst/findAny)

判断(anyMatch/allMatch/noneMatch)

映射(map/flatMap)

转特殊流(mapToInt/mapToDouble/mapToLong/flatMapToDouble/flatMapToInt/flatMapToLong)

收集器(collect)

1.归集(toList/toSet/toMap)

2.统计(count/averaging)

3.分组(partitioningBy/groupingBy)(groupingBy不太理解,以后有时间可以去研究研究)

4.接合(joining)

5.归约(reducing)

归约(reduce)

合并(concat)

跳跃(skip)

返回数组(toArray)

用于调试的(peek)



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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 8引入了Stream API,它是一种处理集合数据的新方式。Stream API提供了一种流式操作的方式,可以对集合进行过滤、映射、排序、聚合等操作,使得代码更加简洁、易读和高效。 Stream是一个来自数据源的元素队列并支持聚合操作。它可以是集合、数组、I/O channel、产生器等。Stream操作可以顺序执行,也可以并行执行。 Java 8 Stream API的特点包括: 1. 延迟执行:Stream操作通常是延迟执行的,只有在终止操作时才会触发实际的计算。 2. 内部迭代:Stream API使用内部迭代的方式,不需要显式地编写循环,使得代码更加简洁。 3. 函数式编程:Stream API支持函数式编程风格,可以通过Lambda表达式来定义操作。 4. 并行处理:Stream API提供了并行处理的能力,可以充分利用多核处理器的优势,提高处理速度。 使用Stream API可以通过一系列的中间操作和终止操作来对集合进行处理。中间操作包括过滤、映射、排序等操作,终止操作包括聚合、收集、遍历等操作。 下面是一些常用的Stream操作方法: 1. filter(Predicate<T> predicate):根据指定条件过滤元素。 2. map(Function<T, R> mapper):将元素进行映射转换。 3. sorted(Comparator<T> comparator):对元素进行排序。 4. distinct():去除重复的元素。 5. limit(long maxSize):限制元素的数量。 6. skip(long n):跳过指定数量的元素。 7. forEach(Consumer<T> action):对每个元素执行指定操作。 8. collect(Collector<T, A, R> collector):将元素收集到集合中。 9. reduce(BinaryOperator<T> accumulator):对元素进行归约操作。 10. parallel():启用并行处理。 以上只是Stream API的一部分常用操作,还有更多的操作方法可以根据具体需求使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值