java中Stream流

Stream流的引入

Stream流完全不是i/o流,按照流水线处理方式来考虑代码中的思想。
JDK1.8之后,我们拥有了Lambda表达式,让代码的中心偏向解决实际问题
Stream流中使用了大量的Lanbda表达式,优化了代码

Stream流的一些特征:
1.带有很多Sreeam流操作的方法,filter,limit,map,sorted,skip…这些方法大多是函数式接口,由lanbda表达式
2.整个Stream模型操作过程中只有执行到count,foreach这些方法时,操作操作真正的执行中的模型,如果不存在结果,中间的所有操作是无效的,这得益于Lambda表达式
3.Stream流是存在一定管道性的Pepelinling流水线
如何获取Stream流
1.所有的Collection集合都可以直接获取对应的流通过.stream();
2.也可以通过Stream类中的静态方法of(T…)
static Stream of(T…);
static Stream of(T t);

Stream常用方法

1.延迟方法:返回值就是接口本身,并没有影响我们做操真正的资源,允许链式操作
例如:filter(xxx).limit(xxx).sorted(xxx).
1.1filter方法过滤作用
Stream filter(Predicate<? super T> condition);

filter是过滤方式,需要的参数是Predicate接口,Predicate是一个函数式接口,可以直接使用Lambda表达运行。
这里返回值类型是Stream类对象,是经过过滤之后的Stream类型,可以进行链式操作
Predicate接口中需要实现的方法
	boolean test(T t);
package com.qfedu.c_streamfunction;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * Stream流对象filter方法演示
 *
 * @author Anonymous 2020/3/12 11:50
 */
public class Demo2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("擀面皮");
        list.add("肉夹馍");
        list.add("冰峰");
        list.add("水盆羊肉");

        Stream<String> stringStream = list.stream().filter(s -> s.length() >= 3);
        stringStream.forEach(System.out::println);
		//终结方法会导致Stream流关闭
        Stream<String> stringStream1 = stringStream.filter(s -> 4 == s.length());
        stringStream1.forEach(System.out::println);
        /*
        Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
            at java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)
            at java.util.stream.ReferencePipeline.<init>(ReferencePipeline.java:94)
            at java.util.stream.ReferencePipeline$StatelessOp.<init>(ReferencePipeline.java:618)
            at java.util.stream.ReferencePipeline$2.<init>(ReferencePipeline.java:163)
            at java.util.stream.ReferencePipeline.filter(ReferencePipeline.java:162)
            at com.qfedu.c_streamfunction.Demo2.main(Demo2.java:23)
         */
    }
}
	

1.2map方法,数据类型转换方法
Stream map(Function<? super T> function);
类型转换操作,得到的一个转换之后数据类型的Stream流对象
这里需要的参数是Functtion函数式接口,
R apply(T t);
T类型的数据转换成R类型数据

package com.qfedu.c_streamfunction;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * Stream流 map映射方法演示
 *
 * @author Anonymous 2020/3/12 14:39
 */
public class Demo3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("1,骚磊,16");
        list.add("2,骚杰,66");
        list.add("3,老黑,46");
        list.add("4,老付,36");
        list.add("5,污云,56");
        list.add("6,帅栋,26");

        System.out.println(list);

        Stream<Person> personStream = list.stream().map(s -> {
            String[] split = s.split(",");
            Person person = new Person();

            person.setId(Integer.parseInt(split[0]));
            person.setName(split[1]);
            person.setAge(Integer.parseInt(split[2]));

            return person;
        });

        personStream.forEach(System.out::println);
    }
}

1.3 limit方法
Stream limit(long maxSize);
对于当前Stream流对象操作的数据进行限制操作,限制个数到maxSize
例如:
Stream流中保存的有10个元素,limit 5 ==> 前五个元素

package com.qfedu.c_streamfunction;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * Stream流对象 limit方法
 *
 * @author Anonymous 2020/3/12 15:03
 */
public class Demo5 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("红旗");
        list.add("领克");
        list.add("吉利");
        list.add("比亚迪");
        list.add("长安");
        list.add("五菱宏光");

        Stream<String> stream = list.stream();
        // @throws IllegalArgumentException if {@code maxSize} is negative
        stream.limit(5).forEach(System.out::println);
    }
}

1.4skip方法
返回值依然是一个Stream流对象,这里跳过当前Stream流对象前n个元素

package com.qfedu.c_streamfunction;

import java.util.ArrayList;

/**
 * Stream流对象 skip方法
 *
 * @author Anonymous 2020/3/12 15:10
 */
public class Demo6 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("陆巡");
        list.add("高R");
        list.add("RS7");
        list.add("s4");
        list.add("霸道");
        list.add("道奇");

        list.stream().skip(2).forEach(System.out::println);
    }
}

1.1.5concat方法
static Stream concat(Stream<? extends T> a, Stream<? extends T> b)
拼接两个Stream流对象,是一个静态方法,得到新的Stream流对象

package com.qfedu.c_streamfunction;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * Stream流 静态成员方法 concat方法
 *
 * @author Anonymous 2020/3/12 15:15
 */
public class Demo7 {
    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> list1 = new ArrayList<>();

        list1.add("陆巡");
        list1.add("高R");
        list1.add("RS7");
        list1.add("s4");
        list1.add("霸道");
        list1.add("道奇");

        // 获取到两个Stream流,其中保存的数据类型都是String类型
        Stream<String> stream = list.stream();
        Stream<String> stream1 = list1.stream();

        Stream<String> concat = Stream.concat(stream, stream1);

       concat.forEach(System.out::println);

    }
}

2.终结方法

2.1.foreach方法
void foreach(Consumer<? super T> action);
终结方法:
需要一个Consumer接口进行操作处理,消耗一个数据
Consumer接口是一个【函数式接口】那就可以使用Lambda表达式
Consumer接口中方法是
void accept(T t);

package com.qfedu.c_streamfunction;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * Stream流foreach方法使用
 *
 * @author Anonymous 2020/3/12 11:39
 */
public class Demo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("蛋炒饭");
        list.add("虎皮青椒");
        list.add("手撕包菜");
        list.add("鲱鱼罐头");

        // 得到List对应的Stream流对象
        Stream<String> stream = list.stream();

        /*
        Stream<String> Stream流,这里操作的是String类型
            匿名内部类的匿名对象作为方法的参数,曾经多么厉害,现在是有点low
         */
        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        // 这里需要的参数是Consumer函数式接口,完成可以使用Lambda表达式完成
        stream.forEach(string -> System.out.println(string));

        // 我们在哪里见过??? 方法引用
        stream.forEach(System.out::println);
    }
}

2.2count方法
long count();
返回当前Stream流对象中有多少个元素
类似有Collection接口下的size(). String的length();
【终结方法】
一旦执行Stream流对象被关闭

package com.qfedu.c_streamfunction;

import java.util.ArrayList;

/**
 * Stream流对象 count方法演示【终结方法】
 *
 * @author Anonymous 2020/3/12 14:50
 */
public class Demo4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("擀面皮");
        list.add("肉夹馍");
        list.add("冰峰");
        list.add("水盆羊肉");

        // 当前Stream流对象中有多少个元素,终结方法
        long count = list.stream().filter(s -> s.length() >= 3).count();
        System.out.println(count);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值