參考示例發下:
Stream介紹
Stream 使用一種相似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。
Stream API能夠極大提升Java程序員的生產力,讓程序員寫出高效率、乾淨、簡潔的代碼。
這種風格將要處理的元素集合看做一種流,流在管道中傳輸,而且能夠在管道的節點上進行處理,好比篩選,排序,聚合等。
Stream有如下特性及優勢
1. 無存儲。Stream不是一種數據結構,它只是某種數據源的一個視圖,數據源能夠是一個數組,Java容器或I/O channel等。
2. 爲函數式編程而生。對Stream的任何修改都不會修改背後的數據源,好比對Stream執行過濾操做並不會刪除被過濾的元素,而是會產生一個不包含被過濾元素的新Stream。
3. 惰式執行。Stream上的操做並不會當即執行,只有等到用戶真正須要結果的時候纔會執行。
4. 可消費性。Stream只能被「消費」一次,一旦遍歷過就會失效,就像容器的迭代器那樣,想要再次遍歷必須從新生成.
示例以下
package net.liuzd.java.completable.future;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Test;
public class StreamTest {
private static Random rand = new Random();
void println(Object val) {
System.out.println(val);
}
class Group {
int id;
String name;
@Override
public String toString() {
return "Group [id=" + id + ", name=" + name + "]";
}
}
class User {
int id;
int age;
int groupId;
String groupName;
String name;
int money;
@Override
public String toString() {
return "User [id=" + id + ", age=" + age + ", name=" + name + ", money=" + money + "]";
}
public int getId() {
return id;
}
public int getGroupId() {
return groupId;
}
public int getMoney() {
return money;
}
}
private List<User> getUserAll() {
int size = rand.nextInt(100);
Map<Integer, User> users = new HashMap<>();
String[] names = new String[] { "趙", "孫", "李", "王", "劉" };
for (int i = 0; i < size; i++) {
User user = new User();
user.id = rand.nextInt(size);
user.age = rand.nextInt(150);
user.groupId = rand.nextInt(5);// 用戶屬於5個組
user.groupName = user.groupId + "- Name";
user.name = rand.nextBoolean() ? names[rand.nextInt(names.length)] : null;
user.money = rand.nextInt(1000);
users.put(user.id, user);
}
return new ArrayList<>(users.values());
}
@Test
public void testFilterNameEmpty() {
//
List<User> users = getUserAll();
// 找出name爲空的用戶
List<User> userNameEmptys = users.stream().filter(user -> user.name == null).collect(Collectors.toList());
//
println("名稱爲空的集合個數:" + userNameEmptys.size());
userNameEmptys.stream().forEach(user -> {
println("名稱爲空:" + user);
});
}
@Test
public void testFilterConditiom() {
//
List<User> users = getUserAll();
// 更復雜的條件
List<User> userNameEmptys = users.stream().filter(user -> {
// 找出名稱爲空的用戶
if (null != user.name) {
return false;
}
// 找出名稱爲空的用戶而且年齡大於等於50的用戶
if (user.age < 50) {
return false;
}
// 找出名稱爲空的用戶而且年齡大於等於50,而且用戶金額小於30的用戶
if (user.money >= 30) {
return false;
}
// 符合條件的用戶
return true;
}).collect(Collectors.toList());
//
println("符合條件的用戶集合個數:" + userNameEmptys.size());
userNameEmptys.stream().forEach(user -> {
println("名稱爲空:" + user);
});
}
@Test
public void testMapOfUserToIds() {
//
List<User> users = getUserAll();
// 找出用戶ID集合
List<Integer> userIds = users.stream().filter(user -> user.id > 0).map(user -> user.id).collect(Collectors
.toList());
//
println("用戶ID的集合個數:" + userIds.size());
userIds.stream().forEach(id -> {
println("ID:" + id);
});
}
@Test
public void testToMap() {
//
List<User> users = getUserAll();
// 找出用戶ID集合
Map<Integer, User> userMap = users.stream().filter(user -> user.id > 0).collect(Collectors.toMap(User::getId,
Function.identity()));
//
println("用戶ID的集合個數:" + userMap.size());
userMap.values().stream().forEach(user -> {
println("User:" + user);
});
}
@Test
public void testToMapConvert() {
//
List<User> users = getUserAll();
// 找出用戶ID集合
List<Group> groups = users.stream().filter(user -> user.id > 0).map(user -> {
Group g = new Group();
g.id = user.groupId;
g.name = user.groupName;
return g;
}).collect(Collectors.toList());
//
println("用戶ID所屬組集合個數:" + groups.size());
groups.stream().forEach(group -> {
println("Group:" + group);
});
}
@Test
public void testGroupingBy() {
//
// 找出組用戶集合
Map<Integer, List<User>> groupUserMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
.groupingBy(User::getGroupId));
//
println("用戶總共屬於組個數:" + groupUserMap.size());
groupUserMap.values().stream().forEach(listUser -> {
println("ListUser:" + listUser);
});
//
Map<Integer, Long> groupCountsMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
.groupingBy(User::getGroupId, Collectors.counting()));
groupCountsMap.entrySet().stream().forEach(group -> {
println("組ID:" + group.getKey() + ",個數:" + group.getValue());
});
//
Map<Integer, Integer> groupUserMoneyMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
.groupingBy(User::getGroupId, Collectors.summingInt(User::getMoney)));
groupUserMoneyMap.entrySet().stream().forEach(group -> {
println("組ID:" + group.getKey() + ",組用戶全部金額:" + group.getValue());
});
//
}
@Test
public void testCollectingAndThen() {
//
List<User> users = getUserAll();
println("用戶個數:" + users.size());
users.addAll(getUserAll());
println("添加後用戶個數:" + users.size());
// 找出組用戶集合
List<User> unique = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(User::getId))), ArrayList::new));
//
println("去除重複後用戶個數:" + unique.size());
//
}
@Test
public void testMapSum() {
//
Stream<String> s = Stream.of("1", "2", "3", "4", "4");
//
long ans = s.collect(Collectors.counting());
println("個數:" + ans);
//
s = Stream.of("1", "2", "3", "4", "4");
Set<String> set = s.collect(Collectors.toCollection(TreeSet::new));
println("經Set後個數:" + set.stream().collect(Collectors.counting()));
//
s = Stream.of("1", "2", "3", "4", "4");
String joined = s.map(Object::toString).collect(Collectors.joining(", "));
println("joined : " + joined);
// 用戶金額總和
int sum = getUserAll().stream().mapToInt(User::getMoney).sum();
println("用戶金額總和 : " + sum);
//
sum = getUserAll().stream().collect(Collectors.summingInt(User::getMoney));
println("用戶金額總和 : " + sum);
//
}
}