JAVA--高级基础开发

day09[Stream 流,方法引用]

第一章: Stream流java

这里的 Stream,是在 Java 8 中,由于 Lambda 带来的函数式编程,引入的一个全新的 Stream 概念,用于解决已有集合中既有的弊端。算法

    1. 概述
  1. 传统集合的遍历代码,几乎全部的集合(Collection,Map 等)都支持间接或直接的遍历操做,而当咱们须要对集合中的元素进行操做的时候,除了必需的添加、删除、获取外,最典型的就是集合的遍历。

//传统的写法编程

public class Test1{数组

    public static void main(String[] args) {数据结构

        ArrayList<String>list=new ArrayList<>();app

        list.add("李文杰");函数式编程

        list.add("李文集");函数

        list.add("李文洁");spa

        list.add("王智雅");对象

        list.add("何舒雅");

        list.add("王文文");

        //传统的写法

        for(String  ss:list){

          System.out.println(ss);

            }

        }

这是一段很是简单的集合遍历操做,集合中的字符串都进行输出操做

    1. for循环遍历的弊端
  1. 为何使用循环?由于要进行遍历,但循环是遍历的惟一方式吗?遍历是指每个元素逐一进行处理,而并非从第一个到最后一个顺次处理的循环,前者是目的,后者是方式。
  2. 试想一下,若是但愿对集合中的元素进行筛选过滤:
  3. 一、将集合 A 根据条件过滤为子集合 B
  4. 二、而后在根据条件过滤为子集合 C

Java jdk8 以前的代码:

 

public class Test1{

    public static void main(String[] args) {

        ArrayList<String>list=new ArrayList<>();

        list.add("李文杰");

        list.add("李文集");

        list.add("李文洁");

        list.add("王智雅");

        list.add("何舒雅");

        list.add("王文文");

        ArrayList<String>li=new ArrayList<>();

        //传统的写法

        for(String  ss:list){

            if(ss.startsWith("李")){

                li.add(ss);

            }

        }

        for(String  ss2: li){

            System.out.println(ss2);

        }

}

}

分析这段代码中两个 for 循环:

一、 首先筛选全部姓李的人

二、 而后存入到新的集合中

三、 最后进行筛选结果的输出

每当咱们须要对集合中的元素进行操做的时候,老是须要进行循环,循环,再循环。循环只 是作事的方式而不是目的,另外一方面,使用线性循环就意味着只能遍历一次,若是但愿再次

遍历,只能在执行一次代码。

  • Lambda 的衍生物 Stream 能给我带来更加优雅简洁的写法

Stream流的优雅写法

//体验Stream 流

public class Test1{

    public static void main(String[] args) {

        ArrayList<String>list=new ArrayList<>();

        list.add("李文杰");

        list.add("李文集");

        list.add("李文洁");

        list.add("王智雅");

        list.add("何舒雅");

        list.add("王文文");

//使用Stream 流输出

        list.stream().filter(s->s.startsWith("")).

filter(s->s.length()==3).forEach(s->System.out.println(s));

//foreach 表明的就是for循环

    }

}

总结为: 获取流,过滤流,过滤流,开头为李,长度为 3,逐一输出,代码中并无体现使用线性循环或其余任何算法进行遍历。

    1. 流式思想的概述
  • 总体来看,流式思想相似于工厂车间的“生产流水线”。
  • Stream 流其实就是一个集合元素的函数模型,它并非集合,也不是数据结构,其自己也不存储任何元素。
  1. Stream 流是一个来自数据源的元素队列。
  • 元素是特定类型的对象,造成一个队列,java 中的 Stream 流不存储元素,而是按需计算。
  • 数据域流的来源,能够是集合、数组等。
  • 当使用一个流的时候,一般包括三个基本步骤:
  • 获取一个数据源-->数据转换,执行操做获取想要的结果,每次转换原有 Stream 流对象不改变,返回一个新的 Stream 对象,这就容许对其操做能够像链条同样排列,造成一个管道。
    1. 获取流Stream
  1. 位于java.util.stream 包中,interface Stream<T>接口是 Java 8 新加入的最经常使用的流接口(这并非一个函数式接口)
  1. List集合 Set集合 数组获取流的方法:
  2. 获取一个流很是简单,有如下几种经常使用方式:
  3. 全部的 Collection 集合(List,Set)均可以经过 stream 默认方法获取流。
  4. Stream 接口的静态方法 of 能够获取数组对应的流.

//Collection 集合获取Stream流

public class Test2 {

    public static void main(String[] args) {

 //List集合获取流

        List<String>list=new ArrayList<>();

        Stream<String>listStream=list.stream();

 

        //Set集合获取流

        Set<String>set=new HashSet<>();

        Stream<String>setStream=set.stream();

 

        //数组获取流Stream

        String[]array={"13","34","65","76","23"};

        Stream<String>stream=Stream.of(array);

    }

}

  1. 根据Map集合获取流:
  • java.util.Map 接口不是 Collection 的子接口,其 K-V 数据结构不符合流元素的单一特征,因此获取对应的流须要分 key、value 或 entry 等状况。

//Map集合获取流Stream流

public class Test2 {

public static void main(String[] args) {

//Map集合获取流

        Map<String,String>map=new HashMap<>();

        //Map集合Stream流获取键

        Stream<String>mapStream=map.keySet().stream();

        //Map集合Stream流获取值

        Stream<String>maps=map.values().stream();

        //Map集合经过EntrySet来获取Stream流,获得键和值

        Stream<Map.Entry<String,String>>entry=map.entrySet().stream();

}

}

 

    1. 经常使用的方法
  1. 延迟方法:返回值类型任然是一个 Stream 对象,所以支持链式调用(除了终结方法以

外,其他方法都是延迟方法) 

  1. 终结方法:返回值类型再也不是 Stream 接口,所以再也不支持链式调用。

1.6  Foreach

  1. 虽然名字叫foreach,可是与加强的for循环不一样。

void  forEach(Consumer<? super T> action) d

该方法接收一个Consumer接口的函数,会将每个流元素交给函数进行处理

基本使用:

public class Test3 {

    public static void main(String[] args) {

        //foreach示例

        Stream<String>stream=Stream.of("李文杰","张文集","王兰君","李军帽");

         stream.forEach(s -> System.out.println(s));

    }

}

1.7  Filter

过滤:能够经过Filter方法将一个流转换为另外一个流

Stream<T> filter(Predicate<? super T> predicate) 

该方法接收一个 Predicate 函数式接口参数

基本使用:

public class Test3 {

    public static void main(String[] args) {

          //Fifter过滤器

Stream<String>stream=Stream.of("李文杰","张文集","王兰君","李军帽");

        Stream<String>newstream=stream.filter(s ->s.startsWith("李"));

        newstream.forEach(s -> System.out.println(s));

    }

}

 

1.8  map映射

1 若是须要将流中的元素映射到另外一个流中,可使用 map 方法.

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

基本使用:

public class Test3 {

    public static void main(String[] args) {

        //map映射

        Stream<String>stream1=Stream.of("12","34","45","66","99");

        Stream<Integer>stream2=stream1.map(s ->Integer.parseInt(s));

        stream2.forEach(s-> System.out.println(s+10));

}

}

1.9 count 统计个数

流经过count方法来计算流中的个数

long  count(); 返回此流中的元素数。

基本使用

//count方法的使用。

public class Test3 {

 public static void main(String[] args) {

//count方法来统计流的个数

        Stream<String>stream3=Stream.of("刘备","张飞","卧龙","凤雏");

        System.out.println("统计流的个数:"+stream3.count());

}

}

2.0  Limit 提取前几个元素

Limit 方法能够对流进行截取,只取前n个。

Stream<T> limit(long maxSize) 

基本使用:

public class Test3 {

public static void main(String[] args) {

//limit方法使用,对流进行截取

      Stream<String>stream4=Stream.of("赵云","关羽","黄忠","马超");

        Stream<String>stream5=stream4.limit(3);

        stream5.forEach(s -> System.out.println(s));

    }

}

2.1 Skip 跳过前几个元素

Skip方法能够对流实现跳过的操做,继续执行如下的数据

Stream<T> skip (long n) ;

若是流的当前长度大于 n,则跳过前 n 个,不然将会获得一个长度为 0 的空流

基本使用:

public class Test3 {

public static void main(String[] args) {

//Skip方法实现对流元素的跳过

        Stream<String>stream5=Stream.of("赵云","关羽","黄忠","马超");

        Stream<String>stream6=stream5.skip(2);

        stream6.forEach(s -> System.out.println(s));

    }

}

2.2 concat组合

若是有两个流,但愿合并成为一个流,那么可使用 Stream 接口静态方法 concat

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 

基本使用:

public class Test3 {

public static void main(String[] args) {

    //concat 若是两个流,但愿合并为一个流,那么就能够进行组合

        Stream<String>stream7=Stream.of("马超");

        Stream<String>stream8=Stream.of("西凉人");

        Stream<String>stream9=Stream.concat(stream7,stream8);

        stream9.forEach(s -> System.out.println(s));}

}

相关文章
相关标签/搜索