Stream簡(jiǎn)介
JAVA8的新特性,更方便的處理數(shù)據(jù),Java把很多東西都封裝好了,我們只要調(diào)用Api就好了真.調(diào)參編程。
例子:
我們先準(zhǔn)備一個(gè)實(shí)體類,方便之后的講解。
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
用來(lái)過(guò)濾數(shù)據(jù)的,下面看一個(gè)例子:將所有性別為女的對(duì)象添加到列表中
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
可以將對(duì)象轉(zhuǎn)換為其他的對(duì)象,下面的例子是獲取所有人的年齡
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.下面的例子是將對(duì)象的名字通過(guò)空格分割放到列表中
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實(shí)現(xiàn)
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實(shí)現(xiàn)1
List<String> list1 = personList.stream()
.map(person -> person.getName().split(" "))
.flatMap(Arrays::stream).collect(Collectors.toList());
list1.forEach(System.out::println);
//用Map + flatMap實(shí)現(xiàn)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
累加用的,下面的例子是將給定的數(shù)進(jìn)行累加
public void reduceTest(){
//第一種reduce方式
Optional sum = Stream.of(1,2,3,4)
//如果沒(méi)有給初始值,那么初始值就是前兩個(gè)
.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)
//如果沒(méi)有給初始值,那么初始值就是前兩個(gè)
.reduce((acc,item) -> acc + item );
System.out.println(sum1.get());
//第三種reduce方式
Integer sum2 = Stream.of(1,2,3,4)
//給了初始值 ,初始值就是第一個(gè)數(shù)0,根據(jù)初始值來(lái)判斷最后返回的類型
.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")
//給了初始值 ,初始值就是第一個(gè)數(shù)0,根據(jù)初始值來(lái)判斷最后返回的類型
.reduce("0",(acc,item) -> acc + item );
System.out.println(sum4);
}
Collect
可以將流轉(zhuǎn)成list、map、等常用的數(shù)據(jù)結(jié)構(gòu)
public void toCollect(){
List<Person> personList = Person.getList();
//將對(duì)象的名字提取出來(lái)存到list里面
List<String> list = personList.stream().map(person -> person.getName()).collect(Collectors.toList());
//將對(duì)象的名字提前出來(lái)存到set里面
Set<String> set = personList.stream().map(person -> person.getName()).collect(Collectors.toSet());;
//將對(duì)象的名字當(dāng)做key,對(duì)象的年齡當(dāng)做age
Map<String,Integer> personMap = personList.stream()
.collect(Collectors.toMap(Person::getName,Person::getAge));
//第二種寫法,其實(shí)和前面的例子一樣
personList.stream()
.collect(Collectors.toMap(person -> person.getName(),person -> person.getAge()));
//這個(gè)遍歷也是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));
//將對(duì)象的名字通過(guò)|拼接起來(lái) 輸出"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);
//將對(duì)象的名字通過(guò)|拼接起來(lái),包含在[]里面 輸出"[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);
// 統(tǒng)計(jì)各個(gè)年齡的人數(shù)放到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 的一個(gè)工具類。
public void optionalTest(){
Person p = new Person();
//of方法里面的參數(shù)不能為空值,否則初始化報(bào)錯(cuò)。
Optional<Object> o = Optional.of(p);
//如果Optional有值則將其返回,否則拋出NoSuchElementException
System.out.println(o.get());
//ofNullable里面的參數(shù)可以為空值。
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不為空,那么將執(zhí)行里面的程序,否則不做處理
o.ifPresent(s -> System.out.println(s));
}