关于java8Stream的简单理解

2021/7/4 22:23:51

本文主要是介绍关于java8Stream的简单理解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

下面直观点了解Stream:

  • Stream是Java8 新增的流特性,目的是让程序员写出高效率、干净、简洁的代码
  • Stream类似于SQL语句,可以对代码进行集合运算和表达
  • Stream就是把元素看成一种流,流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
     

Stream使用格式成如下图 :

构建Stream  ------------中间操作----------------------终端操作 

注意:在没有终端操作 的前提下,中间操作即生成流不会执行 

数据源:分为串行流Stream和并行流parallelStream()

        列举一下构建串行流的方式,与并行流类似 

  •         构建Stream流的4中途径

 

  1.         通过数组 Arrays.stream
/**
 * Created with IntelliJ IDEA.
 *
 * @Author: DIXian
 * @Date: 2021/07/04/19:31
 */
public class Test04 {
    public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6);
        Stream<Integer> stream = integers.stream();
        stream.forEach(System.out::println);
    }
}

   2.          通过集合Collection.stream

    @Test
    public void test01(){

        ArrayList<Object> list = new ArrayList<>();
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.stream().forEach(System.out:: println);

    }
}

 3.        通过Stream的静态of()方法Stream.of

    @Test
    public void test02(){
        Stream.of(2, 3, 4, 5).forEach(System.out :: println);
    }
}

4.        通过创建无限流的两种方式

  • Stream.iterate
  • Stream.generate
  @Test
    public void test03(){
        //seed :给定一个初始值 ,后一个参数 T -> t ,此处加个一个截断操作 limit(10)
        Stream.iterate(0, item -> item+2).limit(10).forEach(System.out :: println);
    }

生成流:即对构建好的进行中间操作

  • filter()
  • map()
  • flatMap()
  • distinct()
  • sorted()
  • peek()
  • limit()
  • skip()

1. filter():filter(): 返回结果生成新的流中只包含满足筛选条件的数据。

 public void test04(){
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6);
        integers.stream().filter(item -> item.equals(1)).forEach(System.out :: println);


    }

2.map():将流中的元素进行再次加工形成一个新流,流中的每一个元素映射为另外的元素。

// 2、map:返回元素的大写类型和哈希值
        List<String> mzc = Arrays.asList("ma", "zhi", "chu");
        List<String> mzcUpperCase = mzc.stream().
                map(n -> n.toUpperCase()).
                collect(Collectors.toList());
        List<Integer> mzcHashCode = mzc.stream().map(n -> n.hashCode()).collect(Collectors.toList());
        System.out.println("mzcUpperCase:"+mzcUpperCase+" ----- mzcHashCode:"+mzcHashCode);

运行结果:

        mzcUpperCase:[MA, ZHI, CHU] ----- mzcHashCode:[3476, 120571, 98480] 

示例场景:取出商品的所有id,就可以这样写(伪代码):

List<Product> productList = productService.selectAll();

List<Integer> pIds = productList.stream().map(p->p.getId).collect(Collectors.toList());

这样就可以拿到所有商品id的集合。

 3.flatMap():扁平化映射,它具体的操作是将多个stream连接成一个stream,这个操作是针对类似多维数组的,比如集合里面包含集合,相当于降维作用,类似list中的addAll()操作

flatMap是将流中的每个元素都放到一个流中,最后将所有的流合并成一个新流,所有流对象中的元素都合并到这个新生成的流中返回。

// flatMap:将多层集合中的元素取出来,放到一个新的集合中去
        List<Integer> num1 = Arrays.asList(1, 2, 3);
        List<Integer> num2 = Arrays.asList(4, 5, 6);
        List<Integer> num3 = Arrays.asList(7, 8, 9);
        List<List<Integer>> lists = Arrays.asList(num1, num2, num3);
        Stream<Integer> outputStream = lists.stream().flatMap(l -> l.stream());
        List<Integer> flatMapResult = outputStream.sorted().collect(Collectors.toList());
        System.out.println(flatMapResult);

运行结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]

示例场景:取出所有部门人员的姓名,就可以这样写(伪代码):

// 1、取出所有部门

List<Department> departments = ...;

// 2、这个时候可以利用flatMap先将所有部门的所有人员汇聚起来

List<Person> persons = departments.stream.flatMap(d->d.getPersonList()).collect(Collectors.toList());

// 3、再利用map()方法取出

4.distinct():顾名思义,将流中的元素去重之后输出。

List<String> mzc = Stream.of("ma","zhi","chu","zhi","shuo","ma")
        .distinct()
        .collect(Collectors.toList());
System.out.println(mzc);

 运行结果:

[ma, zhi, chu, shuo]

5.sorted():这个很简单了,顾名思义,将流中的元素按照自然排序方式进行排序。

// sorted:自然顺序排序
        List<Integer> nums = Arrays.asList(1, 3, 5, 6, 8, 2);
        List<Integer> sortedNum = nums.stream().sorted().collect(Collectors.toList());
        System.out.println(sortedNum);
 
        // sorted:降序排序
        List<Integer> sortedNum2 = nums.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        System.out.println(sortedNum2);
 
        // sorted:使用Comparator
        List<Integer> sortedNums3 = nums.stream().sorted(Comparator.comparing(n -> n)).collect(Collectors.toList());
        System.out.println(sortedNums3);
 
        // 不用stream直接顺序排序
        nums.sort(Comparator.comparing(Integer::intValue));
        System.out.println(nums);
 
        //不用stream直接降序排序
        nums.sort(Comparator.comparing(Integer::intValue).reversed());
        System.out.println(nums);

运行结果:

[1, 2, 3, 5, 6, 8]

[8, 6, 5, 3, 2, 1]

[1, 2, 3, 5, 6, 8]

[1, 2, 3, 5, 6, 8]

[8, 6, 5, 3, 2, 1]

6.peek():对流中每个元素执行操作,并返回一个新的流,返回的流还是包含原来流中的元素。

// peek():
        String[] arr = new String[]{"a","b","c","d"};
        Arrays.stream(arr)
                .peek(System.out::println) //a,b,c,d
                .count();
 
        // peek()+filter()
        Stream.of("ma", "zhi", "chu")
                .filter(e -> e.length() > 2)
                .peek(e -> System.out.println(e))
                .collect(Collectors.toList());

运行结果:

a

b

c

d

zhi

chu

7、limit():顾名思义,返回指定数量的元素的流。返回的是Stream里前面的n个元素。

// limit():取出100中的前十个
        List<Integer> limitNum = IntStream.range(1,100).limit(10)
                .boxed()
                .collect(Collectors.toList());
        System.out.println(limitNum);
 
        // limit():取出前4个单词
        List<String> words = Arrays.asList("ma", "zhi", "chu", "wait", "you", "follow");
        List<String> limitWord = words.stream().limit(4).collect(Collectors.toList());
        System.out.println(limitWord);

 

 

运行结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

[ma, zhi, chu, wait]

8.skip():和limit()相反,将前几个元素跳过(取出)再返回一个流,如果流中的元素小于或者等于n,就会返回一个空的流。

// skip():跳过前面三个单词再返回
    List<String> words = Arrays.asList("ma", "zhi", "chu", "wait", "you", "follow");
    List<String> skipWord = words.stream().limit(4).collect(Collectors.toList());
    System.out.println(skipWord);
 
    // skip():跳过全部单词再返回
    List<String> emptyWord = words.stream().skip(6).collect(Collectors.toList());
    System.out.println(emptyWord);
 
    // skip():跳过超过单词长度的数目再返回
    List<String> emptyWord2 = words.stream().skip(10).collect(Collectors.toList());
    System.out.println(emptyWord);

运行结果:

[91, 92, 93, 94, 95, 96, 97, 98, 99]

[ma, zhi, chu, wait]

[]

[]

 

聚合操作:即对流进行终端操作

  • forEach()
  • forEachOrdered()
  • toArray()
  • reduce()
  • collect()
  • min()
  • max()
  • count()
  • anyMatch()
  • allMatch()
  • noneMatch()
  • findFirst()
  • findAny()

1.forEach():遍历流中的每一个元素,按照指定的方法执行,执行顺序不一定按照流的顺序。

// foreach:遍历流中每一个元素,执行顺序按照流的顺序
Stream.of(1,2,3,4,5,6).forEach(System.out::println);
// foreach:遍历流中每一个元素,执行顺序不一定按照流的顺序,.parallel()表示创建一个并行流
Stream.of(1,2,3,4,5,6).parallel().forEach(System.out::println);

2.forEachOrdered():遍历流中的每一个元素,按照指定的方法执行,执行顺序按照流的顺序。

// forEachOrdered():遍历流中每一个元素,执行顺序按照流的顺序
Stream.of(1,2,3,4,5,6).forEachOrdered(System.out::println);
// forEachOrdered:遍历流中每一个元素,执行顺序按照流的顺序,.parallel()表示创建一个并行流
Stream.of(1,2,3,4,5,6).parallel().forEachOrdered(System.out::println);

运行结果:

1

2

3

4

5

6

1

2

3

4

5

6

3.toArray():将流中的元素放入到一个数组中

// toArray():将流中的元素放入到一个数组中
String[] strings = Stream.of("ma", "zhi", "chu").toArray(String[]::new);
System.out.println(Arrays.toString(strings));

运行结果:[ma, zhi, chu]

4.reduce():这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce。

// reduce():字符串拼接
String reduceStr1 = Stream.of("ma", "zhi", "chu").reduce("", String::concat);
String reduceStr2 = Stream.of("ma", "zhi", "chu").reduce("", (x,y)->x+y);
System.out.println(reduceStr1);
System.out.println(reduceStr2);
// reduce():求和,identity(起始值)为0
Integer total1 = Stream.of(1,2,3,4).reduce(0, Integer::sum);
Integer total2 = Stream.of(1,2,3,4).reduce(0, (x, y) -> x +y);
System.out.println(total1);
System.out.println(total2);
// 求和,sumValue = 10, 无起始值
Integer total3 = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
System.out.println(total3);
// reduce():求最小值
double minValue = Stream.of(-1.1, 8.8, -2.2, -6.6).reduce(Double.MAX_VALUE, Double::min);
System.out.println(minValue);

运行结果:

mazhichu

mazhichu

10

10

10

-6.6

5.collect():是Stream的一个函数,负责收集流。前面我们说中间操作是将一个流转换成另一个流,这些操作是不消耗流的,但是终端操作会消耗流,产生一个最终结果,collect()就是一个规约操作,将流中的结果汇总。结果是由传入collect()中的Collector定义的

// collect():负责收集流,将结果汇总,比如将下面的流中的结果汇总到一个集合中去
List<Integer> skipNum = IntStream.range(1,100).skip(90)
.boxed()
.collect(Collectors.toList());
System.out.println(skipNum);

运行结果:[91, 92, 93, 94, 95, 96, 97, 98, 99]

6.min():返回流中的最小值

// min():返回流中的最小值
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer minNum = nums.stream().min(Integer::compareTo).get();
Integer min = nums.stream().min((x,y) -> x.compareTo(y)).get();
System.out.println(minNum);
System.out.println(min);

运行结果:

1

1

7.max():返回流中的最大值

// max():返回流中的最大值
List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer maxNum = num.stream().max(Integer::compareTo).get();
Integer max = num.stream().max(Comparator.comparing(Function.identity())).get();
System.out.println(maxNum);
System.out.println(max);

运行结果:

6

6

8.count():返回流中元素的数量

// count():返回流中元素的数量
List<Integer> ls = Arrays.asList(1,2,3,4,5);
long count = ls.stream().count();
long count1 = ls.stream().filter(l -> l > 2).count();
System.out.println(count);
System.out.println(count1);

运行结果:

5

3

9.anyMatch():Stream 中只要有一个元素符合传入的断言,就返回 true,否则返回false。

// anyMatch():判断流中数据是否有一个复合断言
List<Integer> ins = Arrays.asList(1,2,3,4,5);
boolean b = ins.stream().anyMatch(l -> l > 2);
boolean b1 = ins.stream().anyMatch(l -> l > 5);
System.out.println(b);
System.out.println(b1);
// anyMatch():判断流中数据是否有一个复合断言,如果流为空,永远返回false
List<Integer> inss = Arrays.asList();
boolean b2 = inss.stream().anyMatch(l -> l > 2);
System.out.println(b2);

运行结果:

true

false

false

10.allMatch():Stream 中所有元素都符合传入的断言时返回 true,否则返回false,流为空时总是返回true。

// allMatch():判断流中元素是否都符合断言条件
List<Integer> ints = Arrays.asList(1,2,3,4,5);
boolean c = ints.stream().allMatch(l -> l > 0);
boolean c1 = ints.stream().allMatch(l -> l > 1);
System.out.println(c);
System.out.println(c1);
// allMatch():判断流中元素是否都符合断言条件,如果流为空,永远返回true
List<Integer> emptyList = new ArrayList<>();
boolean c2 = emptyList.stream().allMatch(e -> e > 1);
System.out.println(c2);

运行结果:

true

false

true

11.noneMatch():Stream 中所有元素都不满足传入的断言时返回 true,否则返回false。

// noneMatch():判断流中元素是否都不符合传入的断言条件
List<Integer> numList = Arrays.asList(1,2,3,4,5);
boolean d = numList.stream().noneMatch(l -> l > 6);
boolean d1 = numList.stream().noneMatch(l -> l > 1);
System.out.println(d);
System.out.println(d1);
// noneMatch():判断流中元素是否都不符合传入的断言条件,流为空时永远返回true
List<Integer> numist = Arrays.asList();
boolean d2 = numist.stream().noneMatch(l -> l > 6);
System.out.println(d2);

运行结果:

true

false

true

12.findFirst():总是返回流中的第一个元素,如果流为空,返回一个空的Optional.

// findFirst():返回流中的第一个元素
List<Integer> integers = Arrays.asList(1, 2, 3);
Optional<Integer> first = integers.stream().findFirst();
System.out.println(first);
System.out.println(first.isPresent()); // 判断是否不等于null,isPresent()相当于!=null的判断
System.out.println(first.get());
//findFirst():返回流中的第一个元素,如果流为空,返回一个空的Optional
List<Integer> lls = Collections.EMPTY_LIST;
Optional<Integer> first1 = lls.stream().findFirst();
System.out.println(first1);
System.out.println(first1.isPresent());

运行结果:

Optional[1]

true

1

Optional.empty

false

13.findAny():返回流中的任意一个元素即可,如果流为空,返回一个空的Optional.

// findAny():返回流中任意一个元素,
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> any = list.stream().findAny();
// 并行流下每次返回的结果会不同
// Optional<Integer> any = list.stream().parallel().findAny();
System.out.println(any);
System.out.println(any.isPresent());
System.out.println(any.get());
// findAny():返回流中任意一个元素,如果流为空,返回一个空的Optional
List<Integer> list1 = Arrays.asList();
Optional<Integer> any1 = list1.stream().findAny();
System.out.println(any1);
System.out.println(any1.isPresent());

运行结果:

Optional[1]

true

1

Optional.empty

false

以上即为Stram的流程操作理解

可参考:https://www.cnblogs.com/mazhichu/p/11983451.html



这篇关于关于java8Stream的简单理解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程