目录
3.1 sorted() / sorted((T, T) -> int)
你需要了解的快捷开发 Java8 stream的使用(一) stream对List集合进行查询、统计等操作
首先介绍一下Collectors 类的静态工厂方法
1.Collectors 类
工厂方法 | 返回类型 | 作用 |
---|---|---|
toList | List<T> |
把流中所有项目收集到一个 List |
toSet | Set<T> |
把流中所有项目收集到一个 Set,删除重复项 |
toCollection | Collection<T> |
把流中所有项目收集到给定的供应源创建的集合menuStream.collect(toCollection(), ArrayList::new) |
counting | Long | 计算流中元素的个数 |
sumInt | Integer | 对流中项目的一个整数属性求和 |
averagingInt | Double | 计算流中项目 Integer 属性的平均值 |
summarizingInt | IntSummaryStatistics | 收集关于流中项目 Integer 属性的统计值,例如最大、最小、 总和与平均值 |
joining | String | 连接对流中每个项目调用 toString 方法所生成的字符串collect(joining(", ")) |
maxBy | Optional<T> |
一个包裹了流中按照给定比较器选出的最大元素的 Optional, 或如果流为空则为 Optional.empty() |
minBy | Optional<T> |
一个包裹了流中按照给定比较器选出的最小元素的 Optional, 或如果流为空则为 Optional.empty() |
reducing | 归约操作产生的类型 | 从一个作为累加器的初始值开始,利用 BinaryOperator 与流 中的元素逐个结合,从而将流归约为单个值累加int totalCalories = menuStream.collect(reducing(0, Dish::getCalories, Integer::sum)); |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果应用转换函数int howManyDishes = menuStream.collect(collectingAndThen(toList(), List::size)) |
groupingBy | Map<K, List<T>> |
根据项目的一个属性的值对流中的项目作问组,并将属性值作 为结果 Map 的键 |
partitioningBy | Map<Boolean,List<T>> |
根据对流中每个项目应用谓词的结果来对项目进行分区 |
2.分组方法
2.1groupingBy
使用 groupingBy() 将数据进行分组,最终返回一个 Map 类型。
根据部门对用户列表进行分组。
/**
* 使用 groupingBy() 分组
*/
@Test
public void groupingByTest()
{
//获取用户列表
List<User> userList = UserService.getUserList();
//根据部门对用户列表进行分组
Map<String,List<User>> userMap = userList.stream().collect(Collectors.groupingBy(User::getDepartment));
//遍历分组后的结果
userMap.forEach((key, value) -> {
System.out.println(key + ":");
value.forEach(System.out::println);
System.out.println("--------------------------------------------------------------------------");
});
}
执行结果:
2.2多级分组
groupingBy 可以接受一个第二参数实现多级分组。
根据部门和性别对用户列表进行分组。
/**
* 使用 groupingBy() 多级分组
*/
@Test
public void multGroupingByTest()
{
//获取用户列表
List<User> userList = UserService.getUserList();
//根据部门和性别对用户列表进行分组
Map<String,Map<String,List<User>>> userMap = userList.stream()
.collect(Collectors.groupingBy(User::getDepartment,Collectors.groupingBy(User::getSex)));
//遍历分组后的结果
userMap.forEach((key1, map) -> {
System.out.println(key1 + ":");
map.forEach((key2,user)->
{
System.out.println(key2 + ":");
user.forEach(System.out::println);
});
System.out.println("--------------------------------------------------------------------------");
});
}
执行结果:
2.3分组汇总
根据部门进行分组,汇总各个部门用户的平均年龄。
/**
* 使用 groupingBy() 分组汇总
*/
@Test
public void groupCollectTest()
{
//获取用户列表
List<User> userList = UserService.getUserList();
//根据部门进行分组,汇总各个部门用户的平均年龄
Map<String, Double> userMap = userList.stream().collect(Collectors.groupingBy(User::getDepartment, Collectors.averagingInt(User::getAge)));
//遍历分组后的结果
userMap.forEach((key, value) -> {
System.out.println(key + "的平均年龄:" + value);
});
}
执行结果:
3.排序方法
3.1 sorted() / sorted((T, T) -> int)
如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,如 Stream。反之, 需要调用 sorted((T, T) -> int) 实现 Comparator 接口。
根据用户年龄进行排序。
/**
* 使用 sorted() 排序
*/
@Test
public void sortedTest()
{
//获取用户列表
List<User> userList = UserService.getUserList();
//根据年龄排序(升序)
userList = userList.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).collect(Collectors.toList());
//推荐:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList());
//降序:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());
//遍历用户列表
userList.forEach(System.out::println);
}
执行结果:
4.安卓兼容
如果是安卓使用stream会报错提示SDK必须大于24才能使用
但是有用户的机型SDK是小于24的,这样肯定不行的。
可以在app\build.gradle中添加引用的库;如下:
implementation 'com.annimon:stream:1.2.1'
注意:
在导包的时候,要导如下:
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
在使用的时候有一些不同
是使用Stream.of()
ArrayList<Person> arrayList = new ArrayList<>();
List<String> names = Stream.of(arrayList)
.map(Person::getName)
.collect(Collectors.toList());