首先流是一个抽象的概念,动态的,具有方向的,代表着数据的一种状态;
流是数据的渠道。因此,流代表了一个对象序列。流操作数据库,如数组或者集合。流本身不存储数据,而是移动数据,再移动过程中可能会对数据执行过滤、排序或者其他操作。然而,一般来说,流操作本身不修改数据源。例如,对流排序不会修改数据源顺序,相反,对流排序会创建一个新流,其中包含排序后的结果。
流api定义了几个流接口,包含在java.util.stream中。BaseStream是基础接口,它定义了所有流都可以使用的基本功能。它是一个泛型接口,其声明如下所示:
public interface BaseStream<T, S extends BaseStream<T, S>>
extends AutoCloseable
stream与Collectors示例:
public class StearmTest {
/**
* 最小值
*/
@Test
public void minTest() {
List<Integer> integers = Arrays.asList(4, 5, 6, 8, 18, 2);
Integer min = integers.stream().min(Comparator.comparing(Integer::intValue)).get();
System.out.println("min:" + min);
}
/**
* 获取最大值
*/
@Test
public void maxTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 8L, 18L, 2L);
Long max = longs.stream().max(Comparator.comparing(Long::longValue)).get();
System.out.println("max:" + max);
}
/**
* 获取count数
*/
@Test
public void countTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 8L, 18L, 2L);
long count = longs.stream().count();
System.out.println("count:" + count);
}
/**
* sort 排序
*/
@Test
public void sortTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 8L, 18L, 2L);
longs.stream().sorted().forEach(System.out::println);
}
/**
* sum求和
*/
@Test
public void sumTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 8L, 18L, 2L);
long sum = longs.stream().sorted().mapToLong(Long::longValue).sum();
System.out.println("sum:" + sum);
}
/**
* filter过滤
*/
@Test
public void filterTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 8L, 18L, 2L);
long count = longs.stream().filter(num -> num > 6).count();
System.out.println("count:" + count);
}
/**
* summaryStatistics,数字聚合
*/
@Test
public void summaryStatisticsTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 6L, 18L, 2L);
LongSummaryStatistics statistics = longs.stream().mapToLong(Long::longValue).summaryStatistics();
System.out.println("avg:" + statistics.getAverage());
System.out.println("count:" + statistics.getCount());
System.out.println("max:" + statistics.getMax());
System.out.println("min:" + statistics.getMin());
System.out.println("sum:" + statistics.getSum());
}
/**
* 去重复 distinct
*/
@Test
public void distinctTest() {
List<String> strings = Arrays.asList("java", "c", "c++", "c++", "python", "go");
strings.stream().distinct().forEach(System.out::println);
}
/**
* 一级分组
*/
@Test
public void groupTest() {
List<Long> longs = Arrays.asList(4L, 5L, 6L, 6L, 18L, 4L);
Map<Long, List<Long>> collect = longs.stream().collect(Collectors.groupingBy(Long::longValue));
collect.forEach((k, v) -> System.out.println(v.size() + "," + k));
}
List<User> userList = Lists.newArrayList();
/**
* 对象集合初始化
*/
@Before
public void initTest() {
List<Address> addressList = Lists.newArrayList();
addressList.add(Address.builder().area("铜山").city("徐州").build());
addressList.add(Address.builder().area("江宁").city("南京").build());
addressList.add(Address.builder().area("雨花").city("南京").build());
userList.add(User.builder().name("张三").sex(1).age(40).addressList(addressList).build());
userList.add(User.builder().name("里斯").sex(2).age(40).addressList(addressList).build());
userList.add(User.builder().name("张三").sex(2).age(40).addressList(addressList).build());
userList.add(User.builder().name("李四").sex(2).age(50).addressList(addressList).build());
}
/**
* 对于toString的拼接
*/
@Test
public void joinTest(){
String join1 = userList.stream().map(User::getName).collect(Collectors.joining());
System.out.println(join1);
String join2 = userList.stream().map(User::getName).collect(Collectors.joining("#"));
System.out.println(join2);
String join3 = userList.stream().map(User::getName).collect(Collectors.joining("#", "{", "}"));
System.out.println(join3); //{张三#里斯#张三#李四}
}
/**
* 分组聚合
*/
@Test
public void group2Test() {
Map<String, List<User>> map = userList.stream().collect(Collectors.groupingBy(user -> user.getName() + "#" + user.getSex()));
map.forEach((k, v) -> {
IntSummaryStatistics statistics = v.stream().mapToInt(User::getAge).summaryStatistics();
System.out.println("avg:" + statistics.getAverage());
System.out.println("count:" + statistics.getCount());
System.out.println("max:" + statistics.getMax());
System.out.println("min:" + statistics.getMin());
System.out.println("sum:" + statistics.getSum());
});
//分组求最大值
userList.stream().collect(Collectors.groupingBy(User::getName,
Collectors.maxBy(Comparator.comparingInt(User::getAge))))
.forEach((k, v) -> System.out.println("最大值是:" + v.get()));
//分组求最小值
userList.stream().collect(Collectors.groupingBy(User::getName,
Collectors.minBy(Comparator.comparingInt(User::getSex))))
.forEach((k, v) -> System.out.println("最小值是:" + v.get()));
//分组求数量
userList.stream().collect(Collectors.groupingBy(User::getName,
Collectors.counting())).forEach((k, v) -> System.out.println("count:" + v));
//分组求和
userList.stream().collect(Collectors.groupingBy(User::getName,
Collectors.summingInt(User::getAge))).forEach((k, v) -> System.out.println("sum:" + v));
}
/**
* 分区,map中key必须是boolean类型
*/
@Test
public void partitionTest() {
//分区
userList.stream().collect(Collectors.partitioningBy(user -> user.getAge() >= 50))
.get(false).forEach(System.out::println);
//分区重载,分区求和
Map<Boolean, Integer> integerMap = userList.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() >= 50,
Collectors.summingInt(User::getAge)));
System.out.println(integerMap.get(false));
//分区重载,分区求数量
Map<Boolean, Long> longMap = userList.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() >= 50,
Collectors.counting()));
System.out.println(longMap.get(true));
//分区重载,分区求最小值,最大值同理
Map<Boolean, Optional<User>> collect = userList.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() >= 50,
Collectors.minBy(Comparator.comparingInt(User::getAge))));
System.out.println(collect.get(false).get());
//分区重载,分区之后再分组
Map<Boolean, Map<String, List<User>>> groupMaps = userList.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() >= 50,
Collectors.groupingBy(User::getName)));
groupMaps.get(false).forEach((k,v)-> System.out.println(v));
//分区重载,分区之后再分组求和
Map<Boolean, Map<String, Integer>> mapMap = userList.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() >= 50,
Collectors.groupingBy(User::getName, Collectors.summingInt(User::getAge))));
mapMap.get(false).forEach((k,v)-> System.out.println("年龄:"+v));
}
/**
* 嵌套循环
* map和peek的区别,一个有返回值,一个无返回值。
*/
@Test
public void forTest() {
//方法1
userList.stream().forEach(user -> {
System.out.println(user.getAge());
user.getAddressList().stream().map(Address::getCity).forEach(System.out::println);
});
//方法2
userList.stream().peek(user -> user.getAddressList().stream().map(Address::getCity).forEach(System.out::println)).forEach(System.out::println);
//方法3
userList.stream().map(User::getAddressList).flatMap(addresses -> addresses.stream().map(Address::getCity)).forEach(System.out::println);
//方法4
userList.stream().map(User::getAddressList).flatMap(List::stream).forEach(System.out::println);
}
/**
* mapping 中左边的参数装入右边list中
*/
@Test
public void mappingTest(){
List<List<Address>> collect0 = userList.stream().collect(Collectors.mapping(User::getAddressList, Collectors.toList()));
List<List<Address>> collect1 = userList.stream().collect(Collectors.mapping(User::getAddressList, Collectors.toCollection(ArrayList::new)));
}
/**
* collectingAndThen类型转换,根据名称去重复之后转list
*/
@Test
public void collectingAndThenTest(){
ArrayList<User> users = userList.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new));
users.forEach(System.out::println);
}
/**
* collect数据接收器
*/
@Test
public void returnTest() {
//转list
List<String> lists = userList.stream().peek(user -> user.setName("hs")).map(User::getName).collect(Collectors.toList());
//转set
Set<String> sets = userList.stream().peek(user -> user.setName("hs")).map(User::getName).collect(Collectors.toSet());
//转map方式1 toMap三个参数分别代表(v1, v2) -> v1)代表若key重复,value则取旧的值
Map<String, User> maps1 = userList.stream().peek(user -> user.setName("hs")).collect(Collectors.toMap(User::getName, user -> user, (v1, v2) -> v1));
//转map方式2 Function.identity()表示取User本身,等同于user->user,这里mapkey必须唯一,否则报错。
Map<String, User> maps2 = userList.stream().collect(Collectors.toMap(User::getName, Function.identity()));
System.out.println(lists);
System.out.println(sets);
System.out.println(maps1);
System.out.println(maps2);
}
/**
* collect数据接收器
*/
@Test
public void returnTest() {
//转list
/**
* 集合拆分
* @param collection
* @param maxSize
* @param splitSize
* @param <T>
* @return
*/
public static <T> List<Collection> splitList(Collection<T> collection, int maxSize, int splitSize) {
if (CollectionUtils.isEmpty(collection)) {
return Collections.emptyList();
}
return Stream.iterate(0, f -> f + 1)
.limit(maxSize)
.parallel()
.map(a -> collection.parallelStream().skip(a * splitSize).limit(splitSize).collect(Collectors.toList()))
.filter(b -> !b.isEmpty())
.collect(Collectors.toList());
}
}
}