java8_02_stream(二)終止操作
阿新 • • 發佈:2019-01-02
三、終止操作
3.1 常見的八種操作
- allMatch——檢查是否匹配所有元素
- anyMatch——檢查是否至少匹配一個元素
- noneMatch——檢查是否沒有匹配的元素
- findFirst——返回第一個元素
- findAny——返回當前流中的任意元素
- count——返回流中元素的總個數
- max——返回流中最大值
- min——返回流中最小值
測試用例
public class Student {
private String name;
private Integer age;
private Integer score;
private Status status;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public Student() {
}
public Student(String name, Integer age, Integer score) {
this .name = name;
this.age = age;
this.score = score;
}
public Student(String name, Integer age, Integer score, Status status) {
this.name = name;
this.age = age;
this.score = score;
this.status = status;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (name != null ? !name.equals(student.name) : student.name != null) return false;
if (age != null ? !age.equals(student.age) : student.age != null) return false;
return score != null ? score.equals(student.score) : student.score == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (age != null ? age.hashCode() : 0);
result = 31 * result + (score != null ? score.hashCode() : 0);
return result;
}
public enum Status{
FREE,
BUSY,
HAPPY
}
}
程式碼示例
public class StreamDemo3 {
/*
測試資料集合
*/
List<Student> students = Arrays.asList(
new Student("張三",18,88, Student.Status.BUSY),
new Student("李四",18,80, Student.Status.BUSY),
new Student("王五",19,60, Student.Status.FREE),
new Student("王五",19,60, Student.Status.BUSY),
new Student("王五",19,60, Student.Status.HAPPY),
new Student("趙六",17,100, Student.Status.HAPPY)
);
@Test
public void test(){
boolean b = students.stream()
.allMatch(s -> s.getAge() > 17);
System.out.println(b);
}
@Test
public void test2(){
boolean b = students.stream()
.anyMatch(s->s.getAge()>17);
System.out.println(b);
}
@Test
public void test3(){
boolean b = students.stream()
.noneMatch(s->s.getAge()>100);
System.out.println(b);
}
@Test
public void test4(){
Optional<Student> studentOptional = students.stream()
.filter(s->s.getStatus().equals(Student.Status.BUSY))
.findFirst();
if (studentOptional.isPresent()){ // 判斷是否為null,避免空指標異常
System.out.println(studentOptional.get()); //獲得結果
}
}
@Test
public void test5(){
Optional<Student> studentOptional = students.stream()
.filter(s->s.getStatus().equals(Student.Status.BUSY))
.findAny(); // 滿足條件的任意一個
if (studentOptional.isPresent()){
System.out.println(studentOptional.get());
}
Optional<Student> studentOptional2 = students.parallelStream()
.filter(s->s.getStatus().equals(Student.Status.BUSY))
.findAny();
if (studentOptional2.isPresent()){
System.out.println(studentOptional2.get());
}
}
@Test
public void test6(){
Long count = students.stream()
.filter(s->s.getStatus().equals(Student.Status.BUSY))
.count();
System.out.println(count);
}
@Test
public void test7(){
Optional<Student> maxScoreStudent = students.stream()
.filter(s->s.getStatus().equals(Student.Status.BUSY))
.max(Comparator.comparingInt(Student::getScore)); //等同於 .max((s1,s2)->Integer.compare(s1.getScore(),s2.getScore()));
System.out.println("busy狀態,分數最多:" +maxScoreStudent.get());
}
@Test
public void test8(){
Optional<Student> studentOptional = students.stream()
.min(Comparator.comparingInt(Student::getAge)); //等同於 .min((s1,s2)-> Integer.compare(s1.getAge(),s2.getAge()));
if (studentOptional.isPresent())
System.out.println(studentOptional.get());
}
}
3.2 歸約
reduce(T identity, BinaryOperator) / reduce(BinaryOperator):將流中的元素反覆結合起來,得到一個值
@Test
public void test9(){
List<Integer> integerList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//求和操作
Integer sum = integerList.stream()
.reduce(0,Integer::sum); //reduce(初始因子,計算演算法)
System.out.println(sum);
//學生分數總和
Optional<Integer> scoreSumOptional = students.stream()
.map(Student::getScore)
.reduce(Integer::sum); //沒有初始因子,所以返回的Optional<T> 集合類,可以避免空指標異常
if (scoreSumOptional.isPresent())
System.out.println(scoreSumOptional.get());
}
@Test
public void test10(){
//需求:名字中,“五”字出現的次數
Optional<Integer> fiveOp = students.stream()
.map(Student::getName)
.flatMap(str ->{ //str->List<Character>-> Stream<Character>
List<Character> characters = new ArrayList<>();
for (Character ch : str.toCharArray()){
characters.add(ch);
}
return characters.stream();
})
.map(ch -> { // ‘五’出現一次,返回 1 ,
if (ch.equals('五') || ch == '五') { //注意 char使用單引號。換為雙引號後容易出錯
return 1;
} else return 0;
}
).reduce(Integer::sum); // 求和
System.out.println(fiveOp.get());
}
3.3 collect() 操作
collect():將流轉換成其他形式。接受一個Collector介面的實現,用於給Stream中元素做彙總的方法
@Test
public void testCollect(){
List<String> nameList = students.stream()
.map(Student::getName)
.collect(Collectors.toList());
nameList.forEach(System.out::println);
System.out.println("---------------------------");
Set<String> nameSet = students.stream()
.map(Student::getName)
.collect(Collectors.toSet());
nameSet.forEach(System.out::println);
System.out.println("---------------------------");
HashSet<String> nameHashSet = students.stream()
.map(Student::getName)
.collect(Collectors.toCollection(HashSet::new)); //沒有toHashSet,只能 toCollection(HashSet::new)
nameHashSet.forEach(System.out::println);
System.out.println("---------------------------");
LinkedList<String> nameLinked = students.stream()
.map(Student::getName)
.collect(Collectors.toCollection(LinkedList::new));
nameLinked.forEach(System.out::println);
}
@Test
public void test11(){
Optional<Integer> integerMaxOptional = students.stream().map(Student::getScore).max(Integer::compareTo);
System.out.println(integerMaxOptional.get());
Optional<Student> minOp = students.stream()
.collect(Collectors.minBy((s1,s2)-> Integer.compare(s1.getAge(),s2.getAge())));
System.out.println("年齡最小的物件:"+ minOp.get());
Optional<Student> minOp2 = students.parallelStream()
.min(Comparator.comparingInt(Student::getAge));
System.out.println("年齡最小的物件:"+ minOp2.get());
IntSummaryStatistics iss = students.stream().collect(Collectors.summarizingInt(Student::getAge));
System.out.println(iss.getAverage()); //平均值
System.out.println(iss.getCount()); //個數
System.out.println(iss.getMax()); // 最大值
System.out.println(iss.getMin()); // 最小值
System.out.println(iss.getSum()); // 和
}
分組操作
@Test
public void test12(){
//普通分組
Map<Student.Status,List<Student>> groupByStatus = students.stream()
.collect(Collectors.groupingBy(Student::getStatus));
System.out.println(groupByStatus);
//多級分組
Map<Student.Status,Map<Integer,List<Student>>> manyGroup = students.stream()
.collect(Collectors.groupingBy(Student::getStatus,Collectors.groupingBy(Student::getAge)));
System.out.println(manyGroup);
Map<Student.Status,Map<String,List<Student>>> manyGroup2 = students.stream()
.collect(Collectors.groupingBy(Student::getStatus,Collectors.groupingBy(s ->{
if (s.getScore() < 60 ) return "未及格";
else if (s.getScore() > 80) return "優秀";
else return "普通";
})));
System.out.println(manyGroup2);
}
分割槽操作:true:xxx,flase:xxx
@Test
public void test13(){
//分割槽,分成滿足條件的部分,和未滿足條件的部分
Map<Boolean,List<Student>> partStudent = students.stream()
.collect(Collectors.partitioningBy(s-> s.getScore() > 75));
System.out.println(partStudent);
//多級分割槽 1->2->4 ...
Map<Boolean,Map<Boolean,List<Student>>> fourPart = students.stream()
.collect(Collectors.partitioningBy(s-> s.getScore() > 75,Collectors.partitioningBy( s2 -> s2.getAge() == 17 )));
System.out.println(fourPart);
}
連線操作
@Test
public void test14(){
String joinStr = students.stream()
.map(Student::getName)
.collect(Collectors.joining(","));
System.out.println(joinStr);
String joinStr2 = students.stream()
.map(Student::getName)
.collect(Collectors.joining(",","+","-"));
System.out.println(joinStr2);
}
總結
Stream使用總結
- 一個數據源(如集合) 如 執行一個查詢,獲得資料集合;
- 一箇中間操作鏈,形成一條流的流水線;
- 一個終端操作,執行流水線,並能生成結果。(eg:count()、collect(toList()) )
常見中間操作
操作 | 返回型別 | 操作引數 | 函式描述符 |
---|---|---|---|
filter | Stream | Predicate | T-> boolean |
map | Stream | Function | T -> R |
limit | Stream | ||
sorted | Stream | Comparator | (T,T) ->int |
distinct | Stream |
常見終端操作
操作 | 型別 | 目的 |
---|---|---|
forEach | 終端 | 消費流中的每個元素並對其應用Lambda。返回void |
count | 終端 | 返回流中元素的個數。返回long |
collect | 終端 | 把流歸約成一個集合,比如List、Map甚至是Integer。 |