day33_Stream(JDK1.8后的接口,本身不是函数式接口)

今日内容

  • Stream流

主要是方法的调用:forEach(终结方法) fiter(过滤),map(映射),skip(跳过),count(组合).

1.Stream流

  JDK1.8引入的新特性。用于解决已有集合类库既有的一些弊端,需要依赖于Lambda表达式

在学习Stream流之前,获取集合中的元素是这样的(需要不断地循环遍历)

public class Demo01Stream{
    public static void main(String[] args){
        //构建一个集合
        List<String>list =new ArrayList<String>();
        list.add("abc123");
        list.add("aaa22");
        list.add("bcd125");
        list.add("abcd120");
        list.add("bbb230");
        //需要字符串中包含数字1的元素取出来
        List<String> list2=new ArrayList<String>();// 已经取出 abc123  bcd125  abcd120
        for(String str:list){
            if(Str.contains("1")){
                list2.add(str);
            }
        }
        //需要集合当中字符串不能超过6个的元素取出来
        List<String> list3 = new ArrayList<String>();
        for(String str:list2){
            if(str.length() <=6){
                list3.add(str);
            }
        }
        //遍历查看最终想要的元素集合
        for(String str : list3){
            System.out.println(str);
        }
    }
}

Stream流的更加方法:(更加简洁)

public class Demo01Stream{
    public static void main(String[] args){
        //构建一个集合   of("abc123","aaa22")
        List<String>list =new ArrayList<String>();
        list.add("abc123");
        list.add("aaa22");
        list.add("bcd125");
        list.add("abcd120");
        list.add("bbb230");
        //需要字符串中包含数字1的元素取出来
        //需要集合当中字符串不能超过6个的元素取出来
        //遍历查看最终想要的元素集合
        //Stream<T>filter(Predicate< ? super T> predicate)返回由榆次给定为此匹配的
        Stream<String> stream = list.strream();       
        Stream<String> stream02=stream.filter(str ->.contains("1"));//子集合A        
        Stream<String> stream03=stream02.filter(str ->str.length()-> 6);//子集合B 
        stream03.forEach(str-> System.out.println(ste));
        //再次优化
        list. strean(). filer(str -> str. contains("1")). filter(str -> str.length() <= 6). forEach(str-> System. out . printIn(str));
    }
}

流式思想概述:

流式思想类似于工厂中的生产流水线

方案中的操作的每一个步骤我们称之为“流”,调用指定的api方法,从一个流中转换为另一个流。

当我们使用一个流的时候,通常需要包含三个基本步骤,1.获取一个数据源--->2.数据转换-->3.执行操作获取想要的操作结果。每次转换都是原有的Stream返回一个新的Stream对象。这样我们就可以像链条一样进行操作。

Stream流 其实是一个集合元素的函数模型它并不是集合,也不是数据结构。其本身并不存储任何元素(地址值)。

Stream流 是一个来自数据源的元素队列

  • 元素是特定类型的对象,形成一个队列,Java当中的Stream并不会存储元素,而是按需计算。

  • 数据源 流的来源。可以是集合,也就是数组等容器。

2.获取流对象

  2.1根据Collection集合获取流对象

  只要是Collection集合的实现类或者是子接口(可变参数是一个数组)都可以通过调用stream默认方法获取流对象

3.Stream流中的常用方法  

  流模型中的操作很多,大致上可以把其中的api方法分成两部分:

  1.延迟方法:返回值类型都是Stream接口自身,因此可以支持链式操作。

  2.终结方法:返回值就不是Stream接口自身,因此不能再进行链式操作。count方法和forEach

  forEach方法:

void forEach(Comsumer<T> consumer);//借助于该函数式接口中的方法accept方法
//Consumer<T> 是一个消费型接口  用来消费一个指定泛型的数据。

  代码:

public class TestForEach{
    public static void main(String[] args){
        //1.获取一个数据源
        Stream<String> stream = Stream.of("abc","aaa","abd","bcd","ddd");
        //2.转换数据
        //3.执行操作获取想要的结果
        stream.forEach(str ->{
            if(str.contains("a")){
                System.out.println(str);
            }
        });
    }
}
//展示的结果
abc aaa abd

  过滤:filter

Stream<T> filter(Predicate<? super T> predicate) 返回有与此给定谓词匹配的此流的元素组成的流。
//借助于Predicate函数是借口当中的抽象方法 test(T t) 对数据进行过滤

  该方法接收一个函数式接口Predicate,可以使用Lambda表达式进行条件的筛选

  java.util.stream.Predicate函数式接口。其中唯一的抽象方法

  boolean test(T t ),该方法会返回布尔类型值,代表指定的条件是否满足,如果条件满足返回true,

  映射:map

  如果你需要将流中的数据映射到另外一个流中,可以使用map中方法。

<R> Stream<R> map(Function<? super T,? extends R> mapper)返回由给定函数应用于此流的元素的结果组成的流。

  该方法接收一个函数式接口Function作为方法参数,可以将当前流中的T数据转换成另外一种R类型的数据。

  Function接口

  java.util.stream.Function函数式接口。其中唯一的抽象方法:

R apply(T t)
    //可以将一种T类型的数据转换为R类型的数据,那么这种转换的动作,我们称之为"映射"

  统计个数:count

  可以向Collection集合当中的size()一样,统计流中的元素个数,通过count方法来实现。

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

  该方法返回一个long类型的值代表值中元素的个数(区别于size()返回值int值)

  代码如下:

public class Demo01Count{
    public static void main(String[] args){
        Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
        //统计个数
        long count = stream.count();
        System.out.println(count);//6
    }
}

  取用流中前几个:limit(限制)

  limit()方法可以对流中的数据进行限制--->截取操作,需要一个参数,设定取用流中前max个数。

Stream<T> limit(long maxSize)//返回由此流的元素组成的流,截取长度不能超过 maxSize。

  参数是一个long类型的,截取的长度不能超过流中最大元素个数;否则不进行操作,

代码:

public class Demo02Limit{
    public static void main(String[] args){
        //准备一个数据源
        //获取数据源
        Stream<Intefer> stream =Stream.of(12,13,14,15,16,20,30);
        //想要截取流中的前五个元素
        Stream<Integer> stream02 = stream.limit(5);
        //查看流中的元素个数
        System.out.pritnln(stream02.count);//5
    }
}

  跳过:skip

  跳过前几个元素,取用后几个元素,可以使用skip方法来实现。

Stream<T> skip(long n)//在丢弃流的第一个n元素后返回由该留的n元素组成的流。

  如果流中的当前个数小于n,你将会得到一个长度为0的空流,反之流中的个数大于n,则会跳过前n个元素

public static void main(String[] args) {    
//1.
    String[] source = {"123","124","125","abc","abd","abe"};
    Stream<String>stream = Stream.of(source);
    //2.跳过前3个元素
    Stream<String> stream2 = stream.skip(source.length);//长度为0的空流
    //3.
    //stream2.forEach(str -> System.out.println(str));
    
    long count = stream2.count();
    System.out.println(count);//0
}

  组合:concat

  如果有两个流,希望合并成一个流,那么可以使用concat静态方法

//创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。
static<T> Stream<T> concat(Stream<? extends T> a,Stream?<? extends T> b)

代码:

public class Demo04Concat{
    public static void main(String[] args){
        //准备两个数据源
        //获取两次数据源
        Stream<Integer> stream =Stream.of(12,13,14,15,16,20,30,);
        Stream<Integer> stream02 = Stream.of(1,2,3,4,5,6,7);
        //把两个六合并到一起
        Stream<Integer> stream03=Stream.concat(Stream.stream02);
        Stream03.forEach(num -> System.out.print(num+""));
        //展示结果:12,13,14,15,16,20,30,1,2,3,4,5,6,7
    }
}

  

原文地址:https://www.cnblogs.com/rxqq/p/14175973.html