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就是直接通过集合获取流。
中间操作 filterListdistinctweeks = 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);//周一周二周三周四周五周六周七
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才算是同一个。
sortedListtestList = 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 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。
flatMapflatMap也同样有几个类似名称的方法,
Stream 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流,这个和之前的都不一样
ListtestList = 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相关的有三个方法:
Optionalreduce(BinaryOperator accumulator); T reduce(T identity, BinaryOperator accumulator); U reduce(U identity, BiFunction accumulator, BinaryOperator combiner);
看一下BinaryOperator源码可以发现继承了 BiFunction
@FunctionalInterface public interface BinaryOperatorextends BiFunction { public static BinaryOperator minBy(Comparator super T> comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; } public static BinaryOperator maxBy(Comparator super T> 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 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集合里也是可以一样的效果的,难道有顺序问题?后面的不想继续看了偷个懒。



