栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java8Stream流操作

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 s6 = Stream.generate(() -> {
            LocalTime time = LocalTime.now();
            return  time.getSecond();
        });

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

中间操作 filter
        List weeks = new ArrayList<>();
        weeks.add("周一");
        weeks.add("周二");
        weeks.add("周三");
        weeks.add("周四");
        weeks.add("周五");
        weeks.add("周六");
        weeks.add("周七");
        weeks.add("下周一");
        weeks.add("下周二");
        Stream 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 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 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 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 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有几个方法名类似的

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

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

flatMap

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

 Stream flatMap(Function> mapper);
IntStream flatMapToInt(Function mapper);
LongStream flatMapToLong(Function mapper);
DoubleStream flatMapToDouble(Function mapper);

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

        List 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 predicate);
boolean allMatch(Predicate predicate);
boolean noneMatch(Predicate predicate);

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

reduce操作

reduce相关的有三个方法:

Optional reduce(BinaryOperator accumulator);

T reduce(T identity, BinaryOperator accumulator);

 U reduce(U identity,
                 BiFunction accumulator,
                 BinaryOperator combiner);

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

@FunctionalInterface
public interface BinaryOperator extends BiFunction {

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

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

再看一下BiFunction源码

@FunctionalInterface
public interface BiFunction {

    R apply(T t, U u);


    default  BiFunction andThen(Function 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集合里也是可以一样的效果的,难道有顺序问题?后面的不想继续看了偷个懒。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号