1、可以通过Collection集合提供的stream()和parallelStream();
List
Stream
2、通过arrays中的静态方法Stream()获取数组流
Person[] per = new Person[10];
Stream
3、通过stream流的静态方法of()
Stream
4、创建无线流
//迭代
Stream
//生成
Stream
中间操作
1、筛选与切片
filter -- 接受lambda,从流中排除某些元素
limit -- 截断流,是元素不超过给定的数量,找到limit条数后就不会在进行其他操作了
skip(n)--跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个则返回一个空值 与limit(n)互补
distinct -- 筛选,通过流所生成元素的hashcode和equal去除重复的元素,如果是自己的定义的对象,需要重写hashcode和equals
List listPer = Arrays.asList(
new Person("zs",16,170),
new Person("ls",20,170),
new Person("ww",5,170),
new Person("zl",66,170),
new Person("zl",66,170)
);
//外部迭代
Iterator iterator = listPer.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
//内部迭代:由stream API自己完成
//中间操作 不会执行任何操作
Stream personStream = listPer.stream().filter(
e->{System.out.println("执行中间操作");
return e.getAge() > 10;
}).skip(2).limit(2).distinct();
//终止操作 一次性执行完全部内容,即”惰性求值“
personStream.forEach(System.out::println);
2、映射
map --接受lambda将元素转换为其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每一个元素上,并将其映射为一个新的元素。
flatMap -- 接受一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有的流连城一个流
List list= Arrays.asList("a","b","c");
list.stream().map(x->x.toUpperCase()).forEach(System.out::println);
map和flatMap的区别
Stream> streamStream = list.stream().map(test8::getStream);
Stream characterStream = list.stream().flatMap(test8::getStream);
public static Stream getStream(String str){
List list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
3、排序
sorted():自然排序(comparable排序 )
sorted(Comparetor com):定制排序(comparetor排序)
List list= Arrays.asList("z","b","c");
list.stream().sorted().forEach(System.out::println);//结果是 b,c,z ,也就是按照字典顺序进行比较排序
List listPer = Arrays.asList(
new Person("zs",16,170),
new Person("ls",20,170),
new Person("ww",5,170),
new Person("zl",66,170),
new Person("zl",66,170)
);
listPer.stream().sorted((e1,e2)->{
if (e1.getHeight()==e2.getHeight()){
return -Integer.compare(e1.getAge(),e2.getAge());//不加 - 号表示使用从大到小,加-号表示从小到大
}else{
return e1.getName().compareTo(e2.getName());
}}).forEach(System.out::println);
}// 结果是:
Person{name='ww', age=5, Height=170}
Person{name='zs', age=16, Height=170}
Person{name='ls', age=20, Height=170}
Person{name='zl', age=66, Height=170}
Person{name='zl', age=66, Height=170}
1、查找与匹配
allMatch -- 检查元素匹配所有元素
anyMatch -- 检查是否至少匹配一个元素
noneMathc -- 检查是否没有匹配所有元素(有匹配的元素,false:代表有匹配的元素,true代表没有匹配的元素)
findFirst --返回第一个元素
findAny -- 返回当前流中的任意元素
count -- 返回流中元素总数
max --返回流中元素的最大值
min -- 返回流中元素最小值
public static void main(String[] args) {
List listPer = Arrays.asList(
new Person("zs",16,170),
new Person("ls",20,170),
new Person("ww",5,170),
new Person("zl",66,170),
new Person("zl",67,171)
);
boolean b = listPer.stream().allMatch(e -> e.getHeight() == 170); //true
boolean zs = listPer.stream().anyMatch(e -> e.getName().equals("zs")); //true
boolean ww = listPer.stream().noneMatch(e -> e.getName().equals("11"));//true
Optional first = listPer.stream().findFirst(); //Optional[Person{name='zs', age=16, Height=170}]
//optional是个容器,如果获取的第一个值为空,就会放到容器中,然后你需要通过orElse()进行另外赋值,如同if-else一样,不赋值依旧会出现异常
//防止空指针异常,这也是java8的特性之一
first.orElse(new Person("zs",16,170));//如果为空就默认新对象
Optional any = listPer.stream().findAny();
//findAny并不是随机地选一个,如果是数据较少,串行地情况下,一般会返回第一个结果,如果是并行的情况,那就不能确保是第一个。(Stream流是串行,parallelStream是并行的))
//获取的是第一个值,此时stream是有顺序的,相当于一个list,把list中的数字按顺序去执行findany,找到第一个,所以是第一个值
//如果此时用filter过滤一下把年龄大于20的留下,按照顺序获取然后一个一个执行findany(),新的流里面首先找到第一个,所以是第一个值
long count = listPer.stream().count(); //5
Optional max = listPer.stream().max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
Optional min = listPer.stream().min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
2、归约
reduce(T identity,BinaryOperation)--可以将流中元素反复结合起来,得到一个值返回值是T
reduce(BinaryOperation) --可以将流中元素反复结合起来,得到一个值返回值是Optional
public static void main(String[] args) {
List listPer = Arrays.asList(
new Person("zs",16,170),
new Person("ls",20,170),
new Person("ww",5,170),
new Person("zl",66,170)
);
List list = Arrays.g(1,2,3,4,5,6,7);
//此种计算是,第一个是起始的操作值,后面是对每个元素的操作方法,第一次读取一个1,x=0,y=1 ,x+y=1
//第二次读取一个2,x=1,y=2,x+y=3
//第三次读取一个3,x=3,y=3,x+y=6
//第四次读取一个4,x=6,y=4,x+y=10
Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
//计算年纪的总和
//上面的返回值是interge是因为你给的起始值是interge类型,下面的返回值是optional因为是没有给起始值,只给运算规则,所以需要放到容器里
Optional reduce1 = listPer.stream().map(Person::getAge).reduce(Integer::sum);
System.out.println(reduce1.get());
3、收集
collect-- 将流转化为其他的形式。接收一个collect接口的实现,用于stream流中的元素汇总
//将对象person中的用户名收集成一个集合
//Collections这个类里面有很多收集的方法,如tolist,toset
List collect = listPer.stream().map(Person::getName).collect(Collectors.toList());
//collections内部没有hash等方法
Collection collect1 = listPer.stream().map(Person::getName).collect(Collectors.toCollection(HashSet::new));
//收集总数
listPer.stream().collect(Collections.count());
//获取年纪的平均值
Double collect2 = listPer.stream().collect(Collectors.averagingInt(Person::getAge));
//总和
IntSummaryStatistics collect23 = listPer.stream().collect(Collectors.summarizingInt(Person::getAge));
//获取员工年纪最大的员工最大的信息
Optional collect3 = listPer.stream().collect(Collectors.maxBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
//获取员工最小年纪
Optional collect3 = listPer.stream().collect(Collectors.minBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
Optional collect4 = listPer.stream().map(Person::getAge).collect(Collectors.minBy(Integer::compare));
System.out.println(collect4.get());
//分组
Map> collect5 = listPer.stream().collect(Collectors.groupingBy(Person::getAge));
#结果是:
#{16=[Person{name='zs', age=16, Height=170}],
#66=[Person{name='zl', age=66, Height=170}],
#20=[Person{name='ls', age=20, Height=170}],
#5=[Person{name='ww', age=5, Height=170}]}
//多级分组,下面是先进行年纪分组,在进行身高分组
Map>> collect6 = listPer.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(e -> {
if (e.getHeight() > 170) {
return "高个";
} else {
return "矮个";
}
})));
#{16={矮个=[Person{name='zs', age=16, Height=170}]},
#66={矮个=[Person{name='zl', age=66, Height=170}]},
#20={矮个=[Person{name='ls', age=20, Height=170}]},
#5={矮个=[Person{name='ww', age=5, Height=170}]}}
//分区,分为true和false区
Map> collect7 = listPer.stream().collect(Collectors.partitioningBy(e -> e.getAge() > 20));
#{false=[Person{name='zs', age=16, Height=170}, Person{name='ls', age=20, Height=170}, Person{name='ww', age=5, Height=170}], true=[Person{name='zl', age=66, Height=170}]}
//other
IntSummaryStatistics collect8 = listPer.stream().collect(Collectors.summarizingInt(Person::getAge));
double average = collect8.getAverage();
long count = collect8.getCount();
long sum = collect8.getSum();
//链接
String collect9 = listPer.stream().map(Person::getName).collect(Collectors.joining("-"));
#结果是:zs-ls-ww-zl
String collect9 = listPer.stream().map(Person::getName).collect(Collectors.joining("-","===","==="));
#结果是:===zs-ls-ww-zl===
ifPresent用法
ifPresent 用于对过滤数据(也可以是流返回的option进)进行判空,如果不未空则为true,空则为false
从源码我们就能看出来
//判断是否为空
Optional dict = orgGrade.stream().filter(org -> org.getValue().equals(String.valueOf(grade))).findFirst();
// 判断是否有值
if(dict.isPresent())//true为真,false为假
System.out.print(dict.getValue())
ifPresent 如果经过过滤条件后,有数据的话就可以进行修改。
Optional firstA= AList.stream()
.filter(a -> "小明".equals(a.getUserName()))
.findFirst()
.ifPresent(a -> {
a.setUserName("明明");
})
以上边是我整理的,如有异议,请回复