流是java8 API的新成員阶捆。允許聲明性方式處理數(shù)據(jù)集合凌节。它的好處就是透明地并行處理钦听,無需寫多線程代碼。
先上一個demo:
實體類:
public class Dish {
private String name;
private boolean vegetarian;
private int calories;
private Type type;
public enum Type{Meat,Fish,Other}
public Dish(String name, boolean vegetarian, int calories, Type type) {
super();
this.name = name;
this.vegetarian = vegetarian;
this.calories = calories;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isVegetarian() {
return vegetarian;
}
public void setVegetarian(boolean vegetarian) {
this.vegetarian = vegetarian;
}
public int getCalories() {
return calories;
}
public void setCalories(int calories) {
this.calories = calories;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
@Override
public String toString() {
return "Dish [name=" + name + ", vegetarian=" + vegetarian + ", calories=" + calories + ", type=" + type + "]";
}
}
查詢calories小于500的食物名稱倍奢。
public class Test {
public static List<Dish> menu=Arrays.asList(
new Dish("pork", false, 800, Type.Meat),
new Dish("beef", false, 700, Dish.Type.Meat),
new Dish("chicken", false, 400, Dish.Type.Fish),
new Dish("french fries", true, 530, Dish.Type.Other),
new Dish("rice", true, 350, Dish.Type.Other));
public static void main(String[] args) {
List<String> lowCaloricDishesName=menu.stream()
.filter(d -> d.getCalories()<500)
.sorted(Comparator.comparing(Dish::getCalories))
.map(Dish::getName)
.collect(toList());
System.out.println(lowCaloricDishesName);
}
}
記得引入的類:
import static java.util.stream.Collectors.toList;
java 8 in action該書中對流的定義:從支持數(shù)據(jù)處理操作的源生產(chǎn)的元素序列朴上。
對于上面的例子:menu.stream() 得到流,數(shù)據(jù)源就是menu娱挨,它提供元素序列(訪問特定值的一組有序值)余指,filter,sorted跷坝,map酵镜,limit,collect對流進行操作柴钻。collect最后處理流返回結(jié)果淮韭。
擴展一些上面的demo,查詢calories大于300的前3個食物名稱贴届。
List<String> threeNames=menu.stream()
.filter(d -> d.getCalories()>500)
.sorted(Comparator.comparing(Dish::getCalories))
.map(Dish::getName)
.limit(3)
.collect(toList());
下面分享流的的幾個特點靠粪。也是和集合不一樣的地方。
只能遍歷一次##
List<String> names=Arrays.asList("Tom","Jim","Joe");
Stream<String> s=names.stream();
s.forEach(System.out::println);
s.forEach(System.out::println);
執(zhí)行兩次s.forEach(System.out::println); 報錯:
java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)
stream has already been operated upon or closed流已經(jīng)被操作或者關閉了毫蚓。這個異常很明顯占键。
外部迭代和內(nèi)部迭代##
直接看demo,查看食物名稱元潘,并且添加到集合中畔乙。
//集合處理方式
List<String> names1=new ArrayList<>();
for (Dish d:menu) {
names1.add(d.getName());
}
//流處理方式
List<String> names2=menu.stream()
.map(Dish::getName)
.collect(toList());
兩者的處理方式很直觀。集合使用foreach外部迭代翩概,而流是內(nèi)部迭代的方式牲距。也就是流幫你處理了。至于foreach钥庇,涉及到并行問題了牍鞠,顯然在某些時候的表現(xiàn)是不如Stream的。
流的幾個常見方法##
中間操作评姨,也就是形成流的流水線难述。
filter, map 参咙,limit龄广,sorted,distinct 返回類型都是Stream<T>蕴侧。
終端操作:
forEach择同,count(注意是long型),collect
forEach使用:
menu.forEach(System.out::println);
menu.forEach(d -> System.out.print(d.getName()+"\t"));