参考示例发下:
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);
//
}
}