Java8新特性----Stream

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8新特性----Stream相关的知识,希望对你有一定的参考价值。


What is Stream ?


注意:


Stream操作三部曲


使用演示:

    /*
    * Stream的三个操作步骤
    *
    * 1.创建stream
    * 2.中间操作
    * 3.终止操作(终端操作)
    *
    * */
    @Test
    void test()
    {
      //1.创建stream
   //(1):可以通过collection系列集合提供的stream()或者parallelStream()
        List<String> list=new ArrayList<>();
        Stream<String> stream = list.stream();
   //(2): 通过Arrays里面的静态方法stream()获取数据流
        People[] peoples=new People[10];
        Stream<People> stream1 = Arrays.stream(peoples);
    //(3):通过stream里面的静态方法of()
        Stream<String> aa = Stream.of("aa", "bb", "cc");
        //(4):创建无限流
         //迭代
      Stream.iterate(0, (x) -> x + 2)
              .limit(10)//中间操作
              .forEach(System.out::println);
    }
}


中间操作


筛选与切片

filter---接收Lambda,从流中排除某些元素

limit(max)---截断流,使其元素不超过给定数量

skip(n)---跳过元素,返回一个扔掉了前n个的元素的流,若流张元素不足n个,则返回一个空流,与limit(n)互补

distinct---筛选,通过流所生成的元素的hashcode()equals()去重复元素


内部迭代: 迭代操作由Stream API完成

终止操作:一次性执行全部内容,即惰性求值

使用演示:

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );

    @Test
    void test()
    {
      //中间操作不会执行任何操作
        Stream<People> s=peopleList.stream().filter(people ->people.getAge()>19);
        //终止操作:一次性执行全部内容,即惰性求值
        s.forEach(System.out::println);
    }
}


外部迭代

      //外部迭代
        Iterator<People> iterator = peopleList.iterator();
        while(iterator.hasNext())
            System.out.println(iterator.next());

limit ===> 短路

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );

    @Test
    void test()
    {
    //当查询到满足条件的两条数据后,就停止迭代,此行为称为短路
peopleList.stream().
        filter(people ->{
            System.out.println("短路");
            return people.getAge()>15;}).
        limit(2).//短路
        forEach(System.out::println);
    }
}


skip ===>跳过前n个元素

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("3号",19,5000),
            new People("4号",20,3500)
    );

    @Test
    void test()
    {
peopleList.stream().
        filter(people ->{
            System.out.println("短路");
            return people.getAge()>15;}).
        skip(2).
        forEach(System.out::println);
    }
}


distinct进行元素去重(自定义类需要重写对应的hashcode和equals方法)

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("2号",21,4000),
            new People("4号",20,3500)
    );

    @Test
    void test()
    {
peopleList.stream().
        distinct().
        forEach(System.out::println);
    }
}


映射

map–接收Lambda,将元素转换为其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

flatMap—接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

map的使用演示:

public class TestMain
{
    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("2号",21,4000),
            new People("4号",20,3500)
    );

    @Test
    void test()
    {
     List<String> list=Arrays.asList("a","b","c");
        //将原先集合里面的小写,全部转换为大写,并输出
     list.stream().map((x)->x.toUpperCase()).forEach(System.out::println);
     //对原先的流是没有影响的
        System.out.println(list);
        System.out.println("------------------------------------------------");
        // peopleList.stream().map(p->p.getName());
        //将原先集合里面的People元素全部转换为String元素
        peopleList.stream().map(People::getName).forEach(System.out::println);
    }
}


flatMap使用演示:

使用前,先看一下下面这个案例:

    void test()
    {
     List<String> list=Arrays.asList("aaa","bbb","ccc");
        Stream<Stream<Character>> sm = list.stream().map(TestMain::getAll);
        //相当于当前sm大流里面存放了三个小流
        sm.forEach(System.out::println);
    }

    public static Stream<Character> getAll(String str)
    {
          List<Character> list=new ArrayList<>();
          for(Character ch:str.toCharArray())
          {
              list.add(ch);
          }
          return list.stream();
    }


显然这里我们将list集合对应的新流中每一个元素,都映射为了一个流,并返回,相当于现在的大流中有三个小流

下面我们需要遍历这些小流,取出里面的值

    void test()
    {
     List<String> list=Arrays.asList("aaa","bbb","ccc");
        Stream<Stream<Character>> sm = list.stream().map(TestMain::getAll);
        //遍历大流的同时,遍历小流,取出小流中的值
        sm.forEach(x-> x.forEach(System.out::println));//效果{{a,a,a},{b,b,b},{c,c,c}}
    }

    public static Stream<Character> getAll(String str)
    {
          List<Character> list=new ArrayList<>();
          for(Character ch:str.toCharArray())
          {
              list.add(ch);
          }
          return list.stream();
    }


显然上面写法比较复杂,下面给出简化写法

    @Test
    void test()
    {
     List<String> list=Arrays.asList("aaa","bbb","ccc");
     //返回值不在是大流嵌套小流,而是一个流
        Stream<Character> characterStream = list.stream()
                .flatMap(TestMain::getAll);// 效果{a,a,a,b,b,b,c,c,c}
        characterStream.forEach(System.out::println);
    }

    public static Stream<Character> getAll(String str)
    {
          List<Character> list=new ArrayList<>();
          for(Character ch:str.toCharArray())
          {
              list.add(ch);
          }
          return list.stream();
    }


map与flatmap的区别


map是将对应的每个小流放入当前大流中构成一个流

flatmap取出集合中的每个元素放入当前的流中,相当于将每个小流里面的元素拿出来组合为一个大流

这里还可以参考add()和addAll()的关系:

     List<String> list=Arrays.asList("aaa","bbb","ccc");
   List list1=new ArrayList();
  list1.add(list);
  list1.addAll(list);
        System.out.println(list1);


排序

sorted()—自然排序(Comparable)

sorted(Comparator com)—定制排序(Comparator)

    List<People> peopleList= Arrays.asList(
            new People("1号",18,3000),
            new People("2号",21,4000),
            new People("2号",21,4000),
            new People("4号",18,3500)
    );
    @Test
    void test()
    {
        //这里people没有实现Comparable接口,因此没有自然排序的功能
        //我们需要定制排序
        peopleList.stream().sorted((x,y)->{
            if(x.getAge()==y.getAge())
                //money按照降序排列
                return -x.money.compareTo(y.getMoney());
            else
                return x.getAge().compareTo(y.getAge());
        }).forEach(System.out::println);
    }


Stream的终止操作如下

查找与匹配

查找与匹配
allMatch--检查是否匹配所有元素
anyMatch---检查是否至少匹配一个元素
noneMatch---检查是否没有匹配所有元素
findFirst---返回第一个元素
findAny---返回当前流中任意元素
count---返回流中元素的总个数
max----返回流中最大值
min---返回流中最小值

演示:

public class TestMain
{
    List<People> peopleList= Arrays.asList(
        new People("1号",18,3000, People.STATUS.BUSY),
        new People("2号",21,4000, People.STATUS.FREE),
        new People("2号",21,4000, People.STATUS.BUSY)

以上是关于Java8新特性----Stream的主要内容,如果未能解决你的问题,请参考以下文章

Java8新特性代码示例(附注释)- 方法引用,Optional, Stream

Java8新特性第3章(Stream API)

Java8新特性—— Stream集合运算流入门学习

Java8新特性:Stream的使用

Java8新特性Stream流之匹配与查找

Java8新特性Stream流之匹配与查找