18.2 Stream
18.2.1 Stream API
- Stream是Java8中处理数组、集合的抽象概念;
- 可以执行非常复杂的查找、过滤、映射;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class TestCreateStream {
public static void main(String[] args) {
//Stream --> 集合、数组
List<String> list = new ArrayList<String>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
list.add("zhaoliu");
list.add("qianqi");
//Stream里面存的是数据的操作,本身不保存数据
//1.创建Stream
Stream<String> s = list.stream();
//2.中间操作
Stream<String> center = s.filter( (str) -> str.length() >= 5 );
//3.终止操作 最终操作
System.out.println("名字长度大于5的是:");
center.forEach( System.out::println);
// center.forEach(new Consumer<String>() {
// @Override
// public void accept(String t) {
// System.out.println(t);
// }
// });
//简化
list.stream().filter( (str2)->str2.length() >= 5).forEach(System.out::println);
}
}
输出结果:
名字长度大于5的是:
zhangsan
wangwu
zhaoliu
qianqi
zhangsan
wangwu
zhaoliu
qianqi
18.2.2 常用方法(中间操作)
- Stream<T> filter(Predicate<? super T> predicate); //过滤
- Stream<T> limit(long maxSize); //截断,不超过给定数量
- Stream<T> distinct(); //筛选,利用hashCode和equals
- <R> Stream map(Function<? super T , ? extends R> mapper);
- Stream<T> sorted(); //自然排序
- Stream<T> sorted(Comparator<? super T> comparator); //定制排序
public class Emp implements Comparable{
private String name;
private int age;
private double score;
@Override
public int hashCode() {
return (int)(this.name.hashCode()+this.age+this.score);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Emp other = (Emp) obj;
if(other.name.equals(this.name) && other.age ==this.age && other.score==this.score) {
return true;
}
return false;
}
@Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + ", score=" + score + "]";
}
public Emp() {
super();
}
public Emp(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
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;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public int compareTo(Object o) {
Emp e = (Emp)o;
return this.age - e.getAge();
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestStreamMethod {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
list.add("zhaoliu");
list.add("qianqi");
list.add("zhangsan");
System.out.println("---filter---");
//filter -->过滤,指定规则
list.stream().filter( (s)->s.startsWith("z") ).filter( (s)->s.contains("s") ).forEach(System.out::println);
System.out.println("---limit---");
//limit --> 截断,返回值不超过指定数量
list.stream().limit(3).forEach(System.out::println);//前三个
System.out.println("---distinct---");
//distinct --> 筛选
list.stream().distinct().forEach(System.out::println);
System.out.println();
List<Emp> elist = new ArrayList<Emp>();
elist.add(new Emp("tom" , 18 , 97));
elist.add(new Emp("alex" , 22 , 100));
elist.add(new Emp("jack" , 24 , 98));
elist.add(new Emp("tom" , 18 , 97));//地址不同,hashCode不相等,equals是相等的
elist.add(new Emp("annie" , 21 , 99));
//不会影响元数据
elist.stream().distinct().forEach(System.out::println);
System.out.println();
elist.forEach(System.out::println);
System.out.println("\n---map---");
//Function(T,R)
//emp --> T getName() -> R
elist.stream().map( (emp) -> emp.getName() ).forEach(System.out::println);
elist.stream().map( (emp) -> emp.getScore() ).forEach(System.out::println);
List<String> strList = Arrays.asList("aaa","bbb","ccc","ddd","eee");
strList.stream().map( (s) -> s.toUpperCase() ).forEach(System.out::println);
strList.stream().map( String::toUpperCase ).forEach(System.out::println);
System.out.println("\n---sorted---");
//sorted排序,流中的元素必须实现Comparable接口
list.stream().sorted().forEach(System.out::println);
elist.stream().sorted().forEach(System.out::println);
}
}
输出结果:
---filter---
zhangsan
zhangsan
---limit---
zhangsan
lisi
wangwu
---distinct---
zhangsan
lisi
wangwu
zhaoliu
qianqi
Emp [name=tom, age=18, score=97.0]
Emp [name=alex, age=22, score=100.0]
Emp [name=jack, age=24, score=98.0]
Emp [name=annie, age=21, score=99.0]
Emp [name=tom, age=18, score=97.0]
Emp [name=alex, age=22, score=100.0]
Emp [name=jack, age=24, score=98.0]
Emp [name=tom, age=18, score=97.0]
Emp [name=annie, age=21, score=99.0]
---map---
tom
alex
jack
tom
annie
97.0
100.0
98.0
97.0
99.0
AAA
BBB
CCC
DDD
EEE
AAA
BBB
CCC
DDD
EEE
---sorted---
lisi
qianqi
wangwu
zhangsan
zhangsan
zhaoliu
Emp [name=tom, age=18, score=97.0]
Emp [name=tom, age=18, score=97.0]
Emp [name=annie, age=21, score=99.0]
Emp [name=alex, age=22, score=100.0]
Emp [name=jack, age=24, score=98.0]
18.2.3 常用方法(终止操作)
- long count(); //返回流中元素的总个数
- void forEach(Consumer<? super T> action); //遍历
- boolean anyMatch(Predicate<? super T> predicate); //是否至少匹配一个
- boolean allMatch(Predicate<? super T> predicate); //是否匹配所有元素
- boolean noneMatch(Predicate<? super T> predicate); //是否没有匹配
- Option<T> findFirst(); //返回第一个
- Option<T> findAny(); //返回任意
- Option<T> min(Comparator<? super T> comparator); //返回最小
- Option<T> max(Comparator<? super T> comparator); //返回最大
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* 最终操作
* @author XH
* */
public class TestEndMethod {
public static void main(String[] args) {
//1.forEach --> 遍历
List<String> list = new ArrayList<String>();
list.add("Tom");
list.add("Rose");
list.add("Jack");
list.add("Alexnder");
list.add("Alex");
list.add("Annie");
list.add("Jane");
list.add("Jim");
//2.count -> 流中元素的个数
System.out.println("---count---");
int count = (int)list.stream().filter( (s) -> s.length() > 3 ).count();
System.out.println("流中有:"+count+"个\n");
System.out.println("---anyMatch---");
boolean b1 = list.stream().filter( (s) -> s.length() > 3 ).anyMatch( (s)->s.startsWith("A"));
System.out.println("以“A”开头的:"+b1+"\n");
System.out.println("---allMatch---");
boolean b2 = list.stream().filter((s)->s.length()>3).allMatch((s)->s.contains("n"));
System.out.println("含有“n”的:"+b2+"\n");
System.out.println("---noneMatch---");
//检查 是否 没有匹配
boolean b3 = list.stream().filter((s)->s.length()>3).noneMatch((s)->s.contains("s"));
System.out.println(b3+"\n");
System.out.println("---findFirst---");
String str = list.stream().filter((s)->s.length()>3).findFirst().get();
System.out.println(str+"\n");
System.out.println("---findAny---");
Optional<String> o = list.stream().filter((s)->s.length()>3).findAny();
System.out.println(o.get());
System.out.println("---Max---");
List<Emp> elist = new ArrayList<Emp>();
elist.add(new Emp("tom" , 18 , 97));
elist.add(new Emp("alex" , 22 , 100));
elist.add(new Emp("jack" , 24 , 98));
elist.add(new Emp("annie" , 21 , 99));
Optional<Emp> max = elist.stream().max((e1,e2)->e1.getAge()-e2.getAge());
System.out.println(max+"\n");
System.out.println("---Min---");
Optional<Emp> min = elist.stream().min((e1,e2)->e1.getAge()-e2.getAge());
System.out.println(min);
}
}
输出结果:
---count---
流中有:6个
---anyMatch---
以“A”开头的:true
---allMatch---
含有“n”的:false
---noneMatch---
false
---findFirst---
Rose
---findAny---
Rose
---Max---
Optional[Emp [name=jack, age=24, score=98.0]]
---Min---
Optional[Emp [name=tom, age=18, score=97.0]]
18.2.4 并行Stream
- parallelStream表示多线程的Stream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class TestStream {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for(int i = 0 ; i < 1000000 ; i++) {
UUID u = UUID.randomUUID();
list.add(u.toString());
}
System.out.println("---串行---");
//串行 --》 一条执行路径 单线程
long start = System.currentTimeMillis();
long count = list.stream().sorted().count();
System.out.println("排序了:"+count);
long end = System.currentTimeMillis();
System.out.println("用时:"+(end - start));
System.out.println();
System.out.println("---并行---");
long start2 = System.currentTimeMillis();
long count2 = list.parallelStream().sorted().count();
System.out.println("排序了:"+count2);
long end2 = System.currentTimeMillis();
System.out.println("用时:"+(end2 - start2));
}
}
输出结果:
---串行---
排序了:1000000
用时:1603
---并行---
排序了:1000000
用时:487