Stream流

Stream流

一:常用的函数式接口

1.Predicate接口

1.1:Predicate接口概述
a:Predicate接口做什么用的
	Predicate接口里面有一个抽象方法Test方法(该方法有一个参数有boolean返回值),
还有几个默认方法(与,或,非),通常用于判断数据类型。
1.2:Predicate接口常用方法
a:抽象方法(test)
public class Demo02 {
    public static void main(String[] args) {
        panBoolean(s->s.startsWith("h"),"h123 ");
    }

    public static void panBoolean(Predicate<String> predicate,String str){
        //Predicate就是一个接口,含有唯一的抽象方法,通常用于筛选数据的数据类型
        boolean bo = predicate.test(str);
        System.out.println(bo);
    }
}

b:默认方法(and, or, negate)
and:
public class Demo03 {
    public static void main(String[] args) {
        panBoolean(s1 ->
                        s1.startsWith("h")
                , s2 ->
                        s2.length() > 3
                , "aslffja");
    }

    public static void panBoolean(Predicate<String> predicate1, Predicate<String> predicate2, String str) {
//        boolean b1 = predicate1.test(str);
//        boolean b2 = predicate2.test(str);
//		System.out.printlin(b1&&b2);
        //和上面是一样的。
        System.out.println(predicate1.and(predicate2).test(str));
    }
}

or:代码的执行逻辑和and方法一样。

negate:
public class Demo04 {
    public static void main(String[] args) {
        panBoolean(s -> s.startsWith("h"),"hewa");
    }

    public static void panBoolean(Predicate<String> predicate,String str){
        //System.out.println(!predicate.test(str));
        //和上面是等价的
        System.out.println(predicate.negate().test(str));
    }
}
1.3:and,or和negate底层
//predicate1.and(predicate2):返回一个(t) -> test(t) && other.test(t)对象。
//test(str):就是调用(t) -> test(t) && other.test(t),将str穿给(t) -> test(t) && other.test(t);并执行。
predicate1.and(predicate2).test(str)

a:and底层代码
default Predicate<T> and(Predicate<? super T> other) {
		//用于判断参数是否为空,如果为空抛出空指针异常
        Objects.requireNonNull(other); 
        //
        return (t) -> test(t) && other.test(t);
    }
    
b:or方法的底层代码和and方法类似

//predicate1.negate():返回一个Predicate子对象为(t) -> !test(t);
//test();:是调用Predicate的实现类的test方法,其实也就是执行(t) -> !test(t)。
//将str传递给(t) -> !test(t);中的t。
predicate1.negate().test(str);

c:negate的底层代码
default Predicate<T> negate() {
        return (t) -> !test(t);
    }

2.Function接口

2.1:Function接口概述
a:Function接口是做什么的
是一个函数式接口,里面有个抽象方法apply(有一个参数和一个返回值)。
默认方法为andThen。通常用于数据转换。
2.2:Function接口常用方法
a:抽象方法(apply)
//将“100”转化为100.
public class Demo05 {
    public static void main(String[] args) {
        changeState(num->Integer.parseInt(num),"100");
    }

    public static void changeState(Function<String, Integer> function, String str) {
        Integer i = function.apply(str);
        System.out.println(i);
    }
}

b:默认方法(andThen)
//表示先后执行
public class Demo06 {
    public static void main(String[] args) {

        changeState(s1->Integer.parseInt(s1),s2->100,"10");
    }

    public static void changeState(Function<String,Integer> function,Function<Integer,Integer> function1,String str){
    //表示先执行function的apply方法,再执行function1的方法。
        Integer i2 = function.andThen(function1).apply(str);
        System.out.println("i2 = " + i2);
    }
}
1.3:andThen底层代码
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {

		//对参数进行判断
        Objects.requireNonNull(after);
        
        //function.andThen(function1).apply(str)
        //function.andThen(function1)返回一个 Function的实现类对象
        //apply(str):执行(T t) -> after.apply(apply(t));,并把str给t.
        return (T t) -> after.apply(apply(t));
    }

二:Stream流

1.Stream的概述

1.1:为什么引出Stream流
用于解决用于解决已有集合类库,和数组既有的弊端。
1.2:Stream流是什么
“Stream流”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,
其本身并不存储任何元素(或其地址值)
1.3:注意
Stream流对象只能被使用,使用一次后不能被再次调用其他方法。
Stream是Java 8新加入的最常用的流接口。

2.怎样获取Stream流(三种)

2.1:Collection转化为Stream流
Collection<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
2.2:Map集合转化为Stream流
叙述:
		因为Map集合是双列集合无法直接获取流,需要将双列集合转化为单列集合

代码:
		Map<String, Integer> map = new HashMap<>();
		
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Stream<Map.Entry<String, Integer>> stream1 = entries.stream();
        
        Set<String> keys = map.keySet();
        Stream<String> stream2 = keys.stream();
        
        Collection<Integer> values = map.values();
        Stream<Integer> stream3 = values.stream();    
2.3:数组转化为Stream流
//必须是引用数据类型。
Integer[] arr = {1,1,3,4};
  //利用Stream的的静态方法,of方法的参数为可变数据类型
Stream<Integer> arr1 = Stream.of(arr);

3.Stream流中常用的方法

3.1:过滤方法(filter)

1.实现代码:

 Stream<String> stream1 = Stream.of("张无忌", "张三丰", "周芷若", "d", "aa");
  //filter方法需要一个Predicate类用来筛选,满足条件加入流。
  //filter方法中需要一个Predicate实现类做参数,对流实行过滤。
  Stream<String> stream2 = stream1.filter(s -> s.length() >= 3);

2.filter方法的执行过程:

将流的每个元素当作参数分别放到,Lambda表达式中进行筛选,如果为true放入流中
否则舍弃。
3.2:将一个流转为另外一个流,元素数据类型不一样(map)
		//根据数组获取Stream流
        Stream<String> stream = Stream.of("10", "110", "100");
        //将Stream流中的每一个元素进行类型转换
        Stream<Integer> stream1 = stream.map(s -> Integer.parseInt(s));
        //将流转化为数组。
        Object[] objects = stream1.toArray();
        //将数组转化为字符串
        System.out.println(Arrays.toString(objects));
总结:
		map方法的执行顺序和filter方法的执行顺序一样。
3.2:取出流中每个元素(forEach)
Stream<String> stream = Stream.of("10", "110", "100");
  //需要一个消费者接口(consumer)
stream.forEach(s-> System.out.println(s));
3.3:求出流的长度(count)
long count = stream.count();
3.4:将两个流链接到一起(Concat静态方法)
//stream1接到stream流的后面
Stream<String> concat = Stream.concat(stream, stream1);
3.6:取前几个元素(limite),跳过前几个元(skip)
		//取出流的前几个元素放到另外一个流中
        Stream<String> stream = Stream.of("10", "110", "100");
        Stream<String> limit = stream.limit(2);
        
        //跳过前几个元素
        Stream<String> stream1 = Stream.of("1", "2", "3");
        Stream<String> skip = stream1.skip(1);
3.7:总结
a:链式调用方法:filter concat(静态方法)  map limit skip
b:非链式调用:ForEach(无返回值), count(返回值为整数)

4.将流中的元素收集到集合和数组中

4.1:将流中的元素收集到集合
a;用到的方法
		//使用 Collector对此流的元素执行 mutable reduction操作
		R collect(Collector collector) 
		
		Collector:收集器接口,通常用Collectors的工具类来获取Collector实现类
	
b:代码
		Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,5,5,5);
        //将流中的元素放到list集合中
        List<Integer> collect = stream.collect(Collectors.toList());
        
        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5,5,5,5);
        //将流中的元素放到set集合中
        Set<Integer> set = stream1.collect(Collectors.toSet());
4.2:将流中的元素收集到数组中
a:
Stream<Integer> stream = Stream.of(1, 2, 3, 4);
//将流收集为Object类型的数组。
Object[] objects = stream.toArray();
System.out.println(Arrays.toString(objects));

b:
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,5,5,5);
Integer[] integers = stream.toArray(a -> new Integer[a]);

5.总结

a:
今天学习了Predicate接口,里面有个test方法(需要一个参数,有一个boolean返回值),
还有一些静态方法and,or,negate(对两个结果进行与,或,非),通常称为数据的判断
类型。

b:
Function接口有一个抽象方法apply(有一个参数,有返回值),还有静态方法andThen
表示。通常称为数据转化器。

c:
Stream是一个模型,可以将集合,数组转化为流,然后可以利用流的一些方法对数
据进行操作比如筛选(需要Predicate实现类参数,)将流中的数据转化为另外一种
类型(需要Function中的实现类)遍历每一个元素(需要一个Costumer一个实现类)
。获取流元素的个数。获取流的前几个元素,获取流的后几个元素然后又将流中的数
据收集到集合数组中。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值