Stream简介
JAVA8的新特性,更方便的处理数据,Java把很多东西都封装好了,我们只要调用Api就好了真.调参编程。
例子:
我们先准备一个实体类,方便之后的讲解。
public class Person {
private String name;
private int age;
private String sex;
public static List<Person> getList(){
List<Person> list = new ArrayList<>();
Person zs = new Person("zs s", 18, "女");
Person ls = new Person("ls s", 18, "男");
Person wmz = new Person("wmz s", 20, "女");
Person zmz = new Person("zmz s", 20, "男");
Person lmz = new Person("lmz ", 25, "男");
return Arrays.asList(zs,ls,wmz ,zmz,lmz);
}
//省略一些getter、setter方法
}
Filter
用来过滤数据的,下面看一个例子:将所有性别为女的对象添加到列表中
public void filterSex(){
List<Person> personList = Person.getList();
//旧的版本
List<Person> personList1 = new ArrayList<>();
for(Person person : personList){
if("女".equals(person.getSex())){
personList1.add(person);
}
}
//用Stream的版本
List<Person> list = personList
.stream()
.filter(person -> "女".equals(person.getSex()))
.collect(Collectors.toList());
}
public void filterSex(){
List<Person> personList = Person.getList();
//旧的版本
List<Person> personList1 = new ArrayList<>();
for(Person person : personList){
if("女".equals(person.getSex())){
personList1.add(person);
}
}
//用Stream的版本
List<Person> list = personList
.stream()
.filter(person -> "女".equals(person.getSex()))
.collect(Collectors.toList());
}
Map
可以将对象转换为其他的对象,下面的例子是获取所有人的年龄
public void getUserAge(){
List<Person> personList = Person.getList();
//旧的版本
List<Integer> personList1 = new ArrayList<>();
for(Person person : personList){
personList1.add(person.getAge());
}
//用Stream的版本1
List<Integer> list = personList.stream().map(person -> person.getAge()).collect(Collectors.toList());
//用Stream的版本2
List<Integer> list1 = personList.stream().map(Person::getAge).collect(Collectors.toList());
//用Stream的版本3
List<Integer> list2 =personList.stream().map(person -> { return person.getAge();}).collect(Collectors.toList());
}
FlatMap
可以处理更深层次的map.下面的例子是将对象的名字通过空格分割放到列表中
public void flatMap(){
List<Person> personList = Person.getList();
//用flatMap
List<String> list = personList.stream()
.flatMap(person -> Arrays.stream(person.getName().split(" "))).collect(Collectors.toList());
list.forEach(System.out::println);
//用map实现
List<Stream<String>> streamList = personList.stream()
.map(person -> Arrays.stream(person.getName().split(" "))).collect(Collectors.toList());
for(Stream<String> s : streamList){
s.map(s1 ->{System.out.println(s1);return s1;}).collect(Collectors.toList());
}
//用Map + flatMap实现1
List<String> list1 = personList.stream()
.map(person -> person.getName().split(" "))
.flatMap(Arrays::stream).collect(Collectors.toList());
list1.forEach(System.out::println);
//用Map + flatMap实现2
List<String> list2 = personList.stream()
.map(person -> person.getName().split(" "))
.flatMap(str -> Arrays.asList(str).stream()).collect(Collectors.toList());
list2.forEach(System.out::println);
}
Reduce
累加用的,下面的例子是将给定的数进行累加
public void reduceTest(){
//第一种reduce方式
Optional sum = Stream.of(1,2,3,4)
//如果没有给初始值,那么初始值就是前两个
.reduce((acc,item) -> {
System.out.println(acc);
System.out.println(item);
System.out.println();
acc += item;
return acc;
});
System.out.println(sum.get());
//第二种reduce方式
Optional sum1 = Stream.of(1,2,3,4)
//如果没有给初始值,那么初始值就是前两个
.reduce((acc,item) -> acc + item );
System.out.println(sum1.get());
//第三种reduce方式
Integer sum2 = Stream.of(1,2,3,4)
//给了初始值 ,初始值就是第一个数0,根据初始值来判断最后返回的类型
.reduce(0,(acc,item) -> {
System.out.println(acc);
System.out.println(item);
System.out.println();
acc += item;
return acc;
});
System.out.println(sum2);
//第四种reduce方式
String sum4 = Stream.of("1","2","3","4")
//给了初始值 ,初始值就是第一个数0,根据初始值来判断最后返回的类型
.reduce("0",(acc,item) -> acc + item );
System.out.println(sum4);
}
Collect
可以将流转成list、map、等常用的数据结构
public void toCollect(){
List<Person> personList = Person.getList();
//将对象的名字提取出来存到list里面
List<String> list = personList.stream().map(person -> person.getName()).collect(Collectors.toList());
//将对象的名字提前出来存到set里面
Set<String> set = personList.stream().map(person -> person.getName()).collect(Collectors.toSet());;
//将对象的名字当做key,对象的年龄当做age
Map<String,Integer> personMap = personList.stream()
.collect(Collectors.toMap(Person::getName,Person::getAge));
//第二种写法,其实和前面的例子一样
personList.stream()
.collect(Collectors.toMap(person -> person.getName(),person -> person.getAge()));
//这个遍历也是Java8的新特性
personMap.forEach((key,value) -> {
System.out.println(key+" "+value);
});
//将Person的用户名存到HashSet中
HashSet<String> hashSet = personList.stream().map(person -> person.getName())
.collect(Collectors.toCollection(() -> new HashSet<>()));
//将Person的用户名存到HashSet中 第二种写法
personList.stream().map(person -> person.getName())
.collect(Collectors.toCollection(HashSet::new));
//将对象的名字通过|拼接起来 输出"zs s|ls s|wmz s|zmz s|lmz s"
String string = personList.stream().map(person -> person.getName())
.collect(Collectors.joining("|"));
System.out.println(string);
//将对象的名字通过|拼接起来,包含在[]里面 输出"[zs s|ls s|wmz s|zmz s|lmz s]"
String string1 = personList.stream().map(person -> person.getName())
.collect(Collectors.joining("|","[","]"));
System.out.println(string1);
// 统计各个年龄的人数放到map中
Map<Integer,Long> personGroup = personList.stream()
.collect(Collectors.groupingBy(Person::getAge,Collectors.counting()));
//遍历
personGroup.forEach((key,value) -> {
System.out.println(key+" "+value);
});
}
Optional
Optional 是用于防止 NullPointerException 的一个工具类。
public void optionalTest(){
Person p = new Person();
//of方法里面的参数不能为空值,否则初始化报错。
Optional<Object> o = Optional.of(p);
//如果Optional有值则将其返回,否则抛出NoSuchElementException
System.out.println(o.get());
//ofNullable里面的参数可以为空值。
Optional<String> optional = Optional.ofNullable(null);
//isPresent():如果值存在返回true,否则返回false
System.out.println(optional.isPresent() ? o.get() : "null");
//orElse():如果有值则将其返回,否则返回指定的其它值
System.out.println(optional.orElse("ball"));
//如果o不为空,那么将执行里面的程序,否则不做处理
o.ifPresent(s -> System.out.println(s));
}