什么是流
流提供了一种让我们在比集合更高的概念级别上指定计算的数据视图。
- -摘抄自Core Java Volume II -Advanced Features
为什么要使用
1、高效
2、写法简洁
JDK支持版本:
JDK8+
DEMO
package stream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toSet;
/**
* Java8 流相关API测试类
* @author zx
*/
public class StreamLearningNote {
public static void main(String[] args) {
/**
* 流的创建部分,用的比较多的是list.stream这个API
*/
Stream<String> stream = Stream.of("1", "2", "3");
Stream<String> stream0 = Arrays.stream("1,2,3".split(","));
List<Integer> array = Lists.newArrayList(1,3,2);
Stream<Integer> stream1 = array.stream();
/**
* 集合排序
*/
List<Integer> list = Lists.newArrayList(1,3,2,5,6,9,7,8);
//倒序排序
Object collect = list.stream().sorted( Comparator.comparingInt(Integer::intValue).reversed()).collect(Collectors.toList());
//结果:[9, 8, 7, 6, 5, 3, 2, 1]
//对元素顺序不要求的可以使用并发流,线程的数量 = CPU的核心数量
Object collect2 = list.parallelStream().sorted( Comparator.comparingInt(Integer::intValue).reversed()).collect(Collectors.toList());
//结果:[9, 8, 7, 6, 5, 3, 2, 1]
/**
* 统计与比较
*/
long count = Stream.of("aa,bb,cc,dd,ee,f".split(",")).filter(item -> item.length() >= 2).count();
//结果:5
int min =Stream.of(1,5,3,9,8,2,6,7).min(Integer::compare).get();
//结果:1
int max = Stream.of(1,5,3,9,8,2,6,7).mapToInt(i -> i).max().getAsInt();
//结果:9
/**
* 对象集合操作
*/
Person person = new Person(1L,"H,I,J",10);
Person person1 = new Person(2L,"B,E",20);
Person person2 = new Person(3L,"CC",30);
Person person3 = new Person(4L,"DD",30);
Person person4 = new Person(3L,"EE",50);
Person person5 = new Person(3L,"EE",510);
//组装对象集合
List<Person> perList = Lists.newArrayList(person,person1,person2,person3,person4,person5);
//将name使用","拆分,然后合并为一整个List<String>
List<String> nameStrList = perList.stream().map(item -> item.getName().split(","))
.map(Arrays::asList).flatMap(Collection::stream).collect(Collectors.toList());
System.out.println(nameStrList);
//结果:[H, I, J, B, E, CC, DD, EE, EE]
//List 转Map
Map<String, Person> collect3 = perList.stream().collect(Collectors.toMap(Person::getName, item -> item));
System.out.println(collect3);
//结果:java.lang.IllegalStateException: Duplicate key
TreeMap<Long, Person> collect3_1 = perList.stream().collect(
Collectors.toMap(Person::getId, Function.identity(), (existingValue, newValue) -> {
throw new IllegalStateException();
}, TreeMap::new));
//结果:java.lang.IllegalStateException: Duplicate key
// (existingValue, newValue) -> existingValue 指定同Key覆盖策略为取第一个值
Map<String, Person> collect3_2 = perList.stream().collect(
Collectors.toMap(Person::getName, item -> item, (existingValue, newValue) -> existingValue));
//结果:{EE=EE_3_510, DD=DD_4_30, CC=CC_3_30, H,I,J=H,I,J_1_10, B,E=B,E_2_20}
Map<Long, Set<Person>> collect3_3 = perList.stream().collect(Collectors.toMap(
Person::getId, Collections::singleton, (a, b) -> {
Set<Person> set = new HashSet<>(a);
set.addAll(b);
return set;
}
));
//结果:{1=[H,I,J_1_10], 2=[B,E_2_20], 3=[EE_3_50, CC_3_30, EE_3_510], 4=[DD_4_30]}
//获取id列表转Set
Set<Long> collect4 = perList.stream().map(Person::getId).collect(toSet());
//结果:[1, 2, 3, 4]
/**
* 对象集合操作-分组
*/
Map<Integer, List<Person>> collect5 = perList.stream().map(personItem -> {
Person personTemp = new Person();
BeanUtils.copyProperties(personItem, personTemp);
personTemp.setName("Name:" + personItem.getName());
return personTemp;
}).collect(Collectors.groupingBy(Person::getAge));
//结果:{50=[Name:EE_3_50], 20=[Name:B,E_2_20], 10=[Name:H,I,J_1_10], 510=[Name:EE_3_510], 30=[Name:CC_3_30, Name:DD_4_30]}
Map<Integer, Set<String>> collect6 = perList.stream().collect(
Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, toSet())));
//结果:{50=[EE], 20=[B,E], 10=[H,I,J], 510=[EE], 30=[CC, DD]}
/**
* 对象集合操作-分组+统计
*/
Map<Integer, Long> collect7 = perList.stream().collect(
Collectors.groupingBy(Person::getAge, Collectors.counting()));
//结果:{50=1, 20=1, 10=1, 510=1, 30=2}
Map<Long, List<Person>> collect8 = perList.stream().collect(Collectors.groupingBy(Person::getId));
//结果:{1=[H,I,J_1_10], 2=[B,E_2_20], 3=[CC_3_30, EE_3_50, EE_3_510], 4=[DD_4_30]}
Map<Long, List<Person>> collect9 = perList.stream().collect(Collectors.groupingByConcurrent(Person::getId));
//结果:{1=[H,I,J_1_10], 2=[B,E_2_20], 3=[CC_3_30, EE_3_50, EE_3_510], 4=[DD_4_30]}
Map<Long, Set<Person>> collect9_1 = perList.stream().collect(Collectors.groupingBy(Person::getId, toSet()));
//结果:{1=[H,I,J_1_10], 2=[B,E_2_20], 3=[EE_3_50, CC_3_30, EE_3_510], 4=[DD_4_30]}
Map<Long, Integer> collect10 = perList.stream().collect(Collectors.groupingBy(Person::getId, Collectors.summingInt(Person::getAge)));
//结果:{1=10, 2=20, 3=590, 4=30}
Map<Long, Optional<Person>> collect11 = perList.stream()
.collect(Collectors.groupingBy(Person::getId, Collectors.maxBy(Comparator.comparing(Person::getAge))));
//结果:{1=Optional[H,I,J_1_10], 2=Optional[B,E_2_20], 3=Optional[EE_3_510], 4=Optional[DD_4_30]}
Map<Long, Optional<String>> collect12 = perList.stream().collect(
Collectors.groupingBy(Person::getId,
Collectors.mapping(Person::getName, Collectors.maxBy(Comparator.comparing(String::length)))));
//结果:{1=Optional[H,I,J], 2=Optional[B,E], 3=Optional[CC], 4=Optional[DD]}
Map<Long, Optional<Integer>> collect13 = perList.stream().collect(
Collectors.groupingBy(Person::getId,
Collectors.mapping(Person::getAge, Collectors.maxBy(Comparator.comparing(Integer::intValue)))));
//结果:{1=Optional[10], 2=Optional[20], 3=Optional[510], 4=Optional[30]}
Map<Boolean, List<Person>> collect14 = perList.stream().collect(Collectors.partitioningBy(p -> p.getAge() > 30));
//结果:{false=[H,I,J_1_10, B,E_2_20, CC_3_30, DD_4_30], true=[EE_3_50, EE_3_510]}
/**
* 对象集合操作-补充
*/
String collect15 = perList.stream().map(Person::getName).collect(joining(","));
//结果:H,I,J,B,E,CC,DD,EE,EE
Map<String, String> collect16 = perList.stream().collect(
Collectors.groupingBy(Person::getName, mapping(Person::getName, joining(","))));
//结果:{EE=EE,EE, DD=DD, CC=CC, H,I,J=H,I,J, B,E=B,E}
//补充,求和
Double totalIncome = alipayOriginBillDataService.selectByOrderDateRangeAndBaseOrderNumber(fromDate, toDate,
bizBaseOrderNumber).stream().map(AlipayOriginBillData::getIncome).reduce((x, y) -> x + y).orElse(0.0);
}
}
非关键代码-Person:
/**
* Person
* @author zx
*/
public class Person {
private Long id;
private String name;
private int age;
public Person() {}
public Person(Long id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return this.name+"_"+this.id+"_"+this.age;
}
@Override
public int hashCode() {
return super.hashCode();
}
}