一、获取stream的方法
1.对数组操作
int[] intArr={1,2,3,45,4,0};
Arrays.stream(intArr).filter(num -> num>0).forEach(num -> System.out.println(num));
2.对零散数据操作
要求零散数据为同一种类型。
Stream.of(1,2,4,3,0).filter(num -> num>0).forEach(num -> System.out.println(num));
Stream.of("a","c","f","d",null).filter(str->StringUtils.isNotEmpty(str)).forEach(str -> System.out.println(str));
3.对集合操作
List<String> list1=new ArrayList<String>();
Collections.addAll(list1, "张无忌","张强","周芷若","小白菜","张三丰","吴王志");
//流式编程最后用forEach输出,每一个name都是list1中的单独对象
list1.stream().filter(e->StringUtils.isNoneEmpty(e))
.filter(e->e.startsWith("张"))
.forEach(name->System.out.print(name+" "));
4.对map操作
Map<String,String> map=new HashMap<String,String>();
map.put("aaa", "111");
map.put("bbb", "222");
map.put("ccc", "333");
map.put("ddd", "444");
//不能直接遍历2个,这里只获取了key的stream
map.keySet().stream().filter(key->StringUtils.isNotEmpty(key))
.forEach(key->System.out.println(key));
//这里遍历了entry,key和value可以一起打印
map.entrySet().stream().filter(entry->Objects.nonNull(entry))
.forEach(entry -> System.out.println(entry));
System.out.println("----------------");
map.entrySet().stream().filter(entry->Objects.nonNull(entry))
.forEach(entry -> System.out.println(entry.getKey()+":"+entry.getValue()));
二、基本方法
1、过滤、取前几条、跳过几个、去重、拼接、map:格式转化
List<String> list1=new ArrayList<String>();
list1.add("张无忌");
list1.add("张无忌");
list1.add("张强");
list1.add("周芷若");
list1.add("小白菜");
list1.add("张三丰");
list1.add("吴王志");
//普通过滤
list1.stream().filter(name -> name.startsWith("张"))
.forEach(name -> System.out.print(name+" "));
System.out.println();
//取前几条
list1.stream().limit(3)
.forEach(name -> System.out.print(name+" "));
System.out.println();
//跳过前几个
list1.stream().skip(3)
.forEach(name -> System.out.print(name+" "));
System.out.println();
//去重
list1.stream().distinct()
.forEach(name -> System.out.print(name+" "));
System.out.println();
//拼接
List<String> list2=new ArrayList<String>();
Collections.addAll(list2, "木婉清","杨过");
Stream.concat(list1.stream(), list2.stream())
.forEach( name -> System.out.print(name+" "));
System.out.println();
//map操作:转换流中的数据规则
List<String> list3=new ArrayList<String>();
Collections.addAll(list3, "小明-13","小王-39","小猪-22");
list3.stream().map(str -> Integer.parseInt(str.split("-")[1]))
.forEach(age -> System.out.print(age+" "));
2.reduce用法
List<String> strList=new ArrayList<>();
Collections.addAll(strList, "A", "B", "C", "D");
// 字符串连接,concat = "ABCD"
String concat1 = strList.stream().reduce("", String::concat);
System.out.println(concat1);
// 过滤,然后字符串连接,concat = "ace"
String concat2 = Stream.of("a", "B", "c", "D", "e", "F").filter(x -> x.compareTo("Z") > 0).reduce("", String::concat);
System.out.println(concat2);
// 求最小值,minValue = -3.0
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
System.out.println(minValue);
// 求和,sumValue = 10, 有起始值
int sumValue1 = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
System.out.println(sumValue1);
// 求和,sumValue = 10, 无起始值
int sumValue2 = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
System.out.println(sumValue2);
三、遍历、统计和收集
这3个是结束操作,使用它们后不能再继续操作了
1.遍历、统计和收集到数组
List<String> list1=new ArrayList<String>();
list1.add("张无忌");
list1.add("张无忌");
list1.add("张强");
list1.add("周芷若");
list1.add("小白菜");
list1.add("张三丰");
list1.add("吴王志");
//遍历
list1.stream().forEach(name -> System.out.print(name+" "));
System.out.println();
//统计
System.out.println(list1.stream().count());
//收集得到数组
String[] strArr=list1.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(strArr));
2.收集到集合
List<String> list1=new ArrayList<String>();
list1.add("张无忌-男-13");
list1.add("张强-男-23");
list1.add("周芷若-女-88");
list1.add("小白菜-女-3");
list1.add("张三丰-男-103");
list1.add("吴王志-女-22");
//收集到list中
List<String> list2=list1.stream().filter(e -> "男".equals(e.split("-")[1]))
.collect(Collectors.toList());
System.out.println(list2);
//收集到set中
Set<String> set=list1.stream().filter(e -> "男".equals(e.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(set);
3.收集到map中
List<String> list1=new ArrayList<String>();
list1.add("张无忌-男-13");
list1.add("张强-男-23");
list1.add("周芷若-女-88");
list1.add("小白菜-女-3");
list1.add("张三丰-男-103");
list1.add("吴王志-女-22");
//第一种方式,不常用
Map<String,Integer> map1=list1.stream().
filter(str -> "男".equals(str.split("-")[1])).
collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String str){
return str.split("-")[0];
}
}, new Function<String, Integer>() {
@Override
public Integer apply(String str){
return Integer.parseInt(str.split("-")[2]);
}
})
);
System.out.println(map1);
//第二种方式,经常使用
Map<String, Integer> map2=list1.stream()
.filter(str -> "男".equals(str.split("-")[1]))
.collect(Collectors.toMap(str -> str.split("-")[0],str -> Integer.parseInt(str.split("-")[2])));
System.out.println(map2);
四、练习
1.过滤奇数,保留偶数
List<Integer> list1=new ArrayList<Integer>();
Collections.addAll(list1, 1,2,3,4,5,6,7,8);
List<Integer> list2=list1.stream().filter(num -> Objects.nonNull(num))
.filter(num -> num%2==0)
.collect(Collectors.toList());
System.out.println(list2);
2.年龄大于24岁的留下,姓名为键,年龄为值
List<String> list1=new ArrayList<String>();
Collections.addAll(list1, "晓丽,23","小钟,56","小王,21","冬梅,83","洋洋,99");
Map<String,Integer> map=list1.stream().filter(str -> StringUtils.isNotEmpty(str))
.filter(str -> Integer.parseInt(str.split(",")[1])>24)
.collect(Collectors.toMap(str -> str.split(",")[0],str -> Integer.parseInt(str.split(",")[1])));
System.out.println(map);
3.一个集合与另一个的交集
//设置2个集合的值
List<String> list1=new ArrayList<String>();
Collections.addAll(list1, "a","b","c","d","e");
List<String> list2=new ArrayList<String>();
Collections.addAll(list2, "c","e","f","q","1");
//取交集
List<String> list1_1=list1.stream().filter(e -> list2.contains(e)).collect(Collectors.toList());
System.out.println(list1_1);
4. 有2个list,一个存放男性信息、一个存放女性信息。男女各保留一些,合并到一起,再封存成对象
List<String> list1=new ArrayList<String>();
Collections.addAll(list1, "李伟伟,23","冯旭,56","老管彤,21","大七哥,83","阿森,99");
List<String> list2=new ArrayList<String>();
Collections.addAll(list2, "杨晓丽,11","小红,46","冬梅,17","杨小薰,66","王鑫,32");
//男的留下名字3个字的前2人
List<String> list1_1=list1.stream().filter(str -> StringUtils.isNotEmpty(str))
.filter(str -> str.split(",")[0].length()==3)
.limit(2).collect(Collectors.toList());
//女的只要姓杨的,且不要第1个
List<String> list2_1=list2.stream().filter(str -> StringUtils.isNotEmpty(str))
.filter(str -> str.startsWith("杨"))
.skip(1).collect(Collectors.toList());
//合并到一起
List<String> listAll=Stream.concat(list1_1.stream(), list2_1.stream()).collect(Collectors.toList());
//封装成Actor对象
List<Actor> listAllFinal=listAll.stream().filter(str -> StringUtils.isNotEmpty(str))
.map(str -> {
//Actor是提取定义好的类,有name和age属性
Actor act=new Actor();
act.setName(str.split(",")[0]);
act.setAge(Integer.parseInt(str.split(",")[1]));
return act;
}).collect(Collectors.toList());
System.out.println(listAllFinal);
5.根据对象中的某个属性去重
//根据Person对象中的age属性去重
//personList中有很多个Person对象
List<Person> distinctPeople = personList.stream().collect(Collectors.toMap(
Person::getAge,
Function.identity(), // 将原对象作为值
(existing, replacement) -> existing // 如果有冲突,保留原来的对象
)).values().stream().collect(Collectors.toList());
//根据姓名和年龄去重
List<Person> distinctPeople = personList.stream().collect(Collectors.toMap(
item -> item.getName()+"_"+item.getAge(),//两个属性拼接到一起,前提是这2个属性重写了toString方法
Function.identity(), // 将原对象作为值
(existing, replacement) -> existing // 如果有冲突,保留原来的对象
)).values().stream().collect(Collectors.toList());