需求
简单流的构建函数of
of就是调用
私有的构造器
// 简单的流 用于学习流的原理
// 定义一个泛型
public class SimpleStream<T> {
// 类上的泛型不能直接使用 需要在方法上定义泛型
// 参数是一个集合
public static <T> SimpleStream<T> of(Collection<T> collection) {
return new SimpleStream<T>(collection);
}
// 构造器私有化
private Collection<T> collection;
private SimpleStream(Collection<T> collection) {
this.collection = collection;
}
}
过滤函数filter
- 过滤需要一个
Predicate
// 过滤 传递一个断言
public SimpleStream<T> filter(Predicate<T> predicate) {
// 创建一个新的集合 尽量不要直接操作原集合
List<T> result = new ArrayList<>();
for (T t : collection) {
//调用predicate的test方法
if (predicate.test(t)) {
result.add(t);
}
}
return new SimpleStream<T>(result);
}
映射map
映射需要的是一个
Function
// 映射 传递一个函数
public <R> SimpleStream<R> map(Function<T,R> function) {
// 创建一个新的集合 尽量不要直接操作原集合
List<R> result = new ArrayList<>();
for (T t : collection) {
// 调用function的apply方法
result.add(function.apply(t));
}
return new SimpleStream<R>(result);
}
终止操作
终止操作需要的是一个
Consumer
// 终止操作 传递一个消费者
public void forEach(Consumer<T> consumer) {
for (T t : collection) {
// 调用consumer的accept方法
consumer.accept(t);
}
}
化简reduce
相邻的两个元素化简为一个参数
,一般来说需要一个初始值
与第一个元素一起化简
// 化简 传递一个初始值和一个二元操作
public T reduce(T init, BinaryOperator<T> operator) {
T result = init;
for (T t : collection) {
result = operator.apply(result, t);
}
return result;
}
// 使用reduce
Integer reduce = SimpleStream.of(list).reduce(0, Integer::sum);
System.out.println(reduce);
收集collect
- 应该提供一个Supplier 新的容器
- 应该提供一个
BiConsumer
,两个参数:新的容器、Stream流中的元素类型
方法collect
// 收集
// supplier 用于创建容器
// consumer 用于向容器中添加元素 C是容器的类型 T是流中元素的类型
public <C> C collect(Supplier<C> supplier, BiConsumer<C, T> consumer) {
// 创建容器
C c = supplier.get();
for (T t : collection) {
// 将流中的元素添加到容器中 c是集合 t是等待添加的元素
// 这里的accept 就是以后的添加的方法体 类似于add push这种类型的
consumer.accept(c, t);
}
return c;
}
收集到set中
// collect方法的使用 添加到set集合中
HashSet<Object> collect = SimpleStream.of(list)
.collect(HashSet::new, HashSet::add);
Stream.of(collect).forEach(System.out::println);
收集到 StringBuilder
// collect 添加到StringBuilder中
StringBuilder collect1 = SimpleStream.of(list)
.collect(StringBuilder::new, StringBuilder::append);
System.out.println(collect1.toString());
收集到map中
- 如果有现成的add或者append自然最好,没有的话就需要使用
函数对象来自定义
了- map.
getOrDefault
(i, 0); 如果map中有这个key就返回这个key的值 如果没有就返回默认值
// collect 添加到map中 统计每个元素出现的次数
Map<Integer, Integer> collect2 = SimpleStream.of(list)
.collect(HashMap::new, (map, i) -> {
// getOrDefault 如果map中有这个key就返回这个key的值 如果没有就返回默认值
Integer count = map.getOrDefault(i, 0);
// 将原本的值+1 重新放入map中
map.put(i, count + 1);
});
collect2.forEach((k, v) -> System.out.println(k + "出现了" + v + "次"));