java8Stream流操作

stream创建

        String[] weeks = new String[]{"周一","周二","周三"};
        Stream s1 = Arrays.stream(weeks);
        Stream s2 = Stream.of(weeks);
        Stream s3 = Stream.of("123");
        Stream s4 = Arrays.asList(weeks).stream();
        Stream s5 = Stream.iterate(0,x->x+1);
        Stream<Integer> s6 = Stream.generate(() -> {
            LocalTime time = LocalTime.now();
            return  time.getSecond();
        });

其中s2,s3的创建方法的源码其实也用了s1的方法来实现的,s5,s6都是无线流,就是一直生成元素,s4就是直接通过集合获取流。

中间操作

filter

        List<String> weeks = new ArrayList<>();
        weeks.add("周一");
        weeks.add("周二");
        weeks.add("周三");
        weeks.add("周四");
        weeks.add("周五");
        weeks.add("周六");
        weeks.add("周七");
        weeks.add("下周一");
        weeks.add("下周二");
        Stream<String> s1 = weeks.stream();
        s1.filter((x) -> { return x.length() < 3;}).forEach(System.out::print);//周一周二周三周四周五周六周七

distinct

hashCode方法保证一样

     public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Test1112 test1112 = (Test1112) o;
            return Objects.equals(name, test1112.name);
        }
        @Override
        public int hashCode() {
            return 5*age+name.hashCode();
        }
    }
    public  void test2(){
        List<Test1112> testList = new ArrayList<>();
        Test1112 day1 = new Test1112("f",1);
        Test1112 day2 = new Test1112("a",2);
        testList.add(day1);
        testList.add(day2);
        System.out.println("day1.hashCode == day2.hashCode :"+(day1.hashCode() == day2.hashCode()));//true
        System.out.println("day1.equals(day2) :"+(day1.equals(day2)));//false
        testList.stream().distinct().forEach(x -> {
            System.out.println(x.toString());
        });//打印出 两个
    }

将两个对象的name属性改成一样的

    public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Test1112 test1112 = (Test1112) o;
            return Objects.equals(name, test1112.name);
        }
        @Override
        public int hashCode() {
            return 5*age+name.hashCode();
        }
    }
    public  void test2(){
        List<Test1112> testList = new ArrayList<>();
        Test1112 day1 = new Test1112("a",1);
        Test1112 day2 = new Test1112("a",2);
        testList.add(day1);
        testList.add(day2);
        System.out.println("day1.hashCode == day2.hashCode :"+(day1.hashCode() == day2.hashCode()));//false
        System.out.println("day1.equals(day2) :"+(day1.equals(day2)));//true
        testList.stream().distinct().forEach(x -> {
            System.out.println(x.toString());
        });//打印出 两个
    }

将名称和age属性都改成一样的

 @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Test1112 test1112 = (Test1112) o;
            return Objects.equals(name, test1112.name);
        }
        @Override
        public int hashCode() {
            return 5*age+name.hashCode();
        }
    }
    public  void test2(){
        List<Test1112> testList = new ArrayList<>();
        Test1112 day1 = new Test1112("a",2);
        Test1112 day2 = new Test1112("a",2);
        testList.add(day1);
        testList.add(day2);
        System.out.println("day1.hashCode == day2.hashCode :"+(day1.hashCode() == day2.hashCode()));//true
        System.out.println("day1.equals(day2) :"+(day1.equals(day2)));//true
        testList.stream().distinct().forEach(x -> {
            System.out.println(x.toString());
        });//打印出 1

最终发现:distinct去重的依据是hashCode和equal方法都返回true才算是同一个。

sorted

        List<Test1112> testList = new ArrayList<>();
        Test1112 day2 = new Test1112("周二",5);
        Test1112 day1 = new Test1112("周一",10);
        Test1112 day3 = new Test1112("周三",6);
        testList.add(day1);
        testList.add(day2);
        testList.add(day3);
        testList.stream().sorted(Comparator.comparing(((x)->{return x.getAge();}),(age1,age2)->{return age1 - age2 ;})).forEach(System.out::print);

sorted方法可以放入自定义比较器,我这里选择的是放入两个参数的比较器,第一个参数我是用来确定两者比较的字段,我选用age字段的值进行比较,然后第二个参数就是比较的逻辑,age大的就是排在后面

map操作

map有几个方法名类似的

 <R> Stream<R> map(Function<? super T, ? extends R> mapper)
IntStream mapToInt(ToIntFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
 testList.stream().map(x -> {return  x.getAge();}).forEach(x -> System.out.println(x));

我看效果就是把之前的元素进行一定的处理,改变了之前stream的泛型对象,然后再返回,当然也可以不改变泛型,我这边是改变了之前的stream泛型,之前是 泛型是Test1112对象,后来变成了Intger。

flatMap

flatMap也同样有几个类似名称的方法,

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);

这边参数是一个Function 函数式接口,并且这个函数式接口的返回对象还是一个stream流,这个和之前的都不一样

        List<Test1112> testList = new ArrayList<>();
        Test1112 day2 = new Test1112("周二,下周二",33);
        Test1112 day1 = new Test1112("周一,下周一",12);
        Test1112 day3 = new Test1112("周三",31);
        testList.add(day1);
        testList.add(day2);
        testList.add(day3);
        testList.stream().flatMap(x -> {return Stream.of(x.getName().split(","));}).forEach(System.out::print);//周一下周一周二下周二周三

我想如果是组织树形式的数据集合用flatMap是不是就可以将这个组织树上的数据都给取下来,也就是扁平化成一个组织类型的集合。

anyMatch,noneMatch,allMatch

boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);

可以看到返回结果是一个boolean值,是一个终止操作
findAny findFirst 也是一个终止操作,返回一个对象,其中findAny好像也一直返回第一个,但是我百度说是不一定的,也就没有深究。

reduce操作

reduce相关的有三个方法:

Optional<T> reduce(BinaryOperator<T> accumulator);

T reduce(T identity, BinaryOperator<T> accumulator);

<U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);

看一下BinaryOperator源码可以发现继承了 BiFunction<T,T,T> 这个函数式接口

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {

    public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }

    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }
}

再看一下BiFunction源码

@FunctionalInterface
public interface BiFunction<T, U, R> {

    R apply(T t, U u);


    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }
}

里面的 R apply(T t, U u)方法,R参数式作为返回结果,所以reduce里的BinaryOperator accumulator函数式接口参数,就是两个形参,并且式有一个返回结果的方法,开始demo。
数据格式:

 		 Test1112 day2 = new Test1112("周一",31);
        Test1112 day1 = new Test1112("周二",32);
        Test1112 day3 = new Test1112("周三",33);

一个参数的:

        System.out.println(testList.stream().reduce((x,y) -> {returny.getAge()+x.getAge();}).get());

刚开始reduce里的函数式接口我是这么写的,但是报错,提示Bad return type in lambda expression: int cannot be converted to Test1112
说类型不匹配,我想testList.stream()里的泛型对象式Test1112,但是这里的返回结果是一个String,原来返回结果还要是一个Test1112对象才行,修改一下:

        System.out.println(testList.stream().reduce((x,y) -> {return new Test1112(x.getName()+y.getName(),y.getAge()+x.getAge());}).get());
        // Test1112{name='周一周二周三', age=96}

看结果就知道是先将周一 周二 的name 拼接,age相加之后,作为返回结果,再次与周三的做相同操作。

有两个参数方法:
T reduce(T identity, BinaryOperator accumulator);可以看到多出来的参数是一个对象,并且就是stream流泛型对象,我不清楚能干嘛,也是一样的我试了一下效果:

        System.out.println(testList.stream().reduce(new Test1112("周四",4),(x,y)->{return new Test1112(x.getName()+y.getName(),x.getAge()+y.getAge());}));
//        Test1112{name='周四周一周二周三', age=100}

也是一样的拼接,那直接把周四加到testList集合里也是可以一样的效果的,难道有顺序问题?后面的不想继续看了偷个懒。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值