// 1, 2, 3, 4, 5
.forEach(System.out :: println);
集合Set去重:
Arrays.asList(1, 2, 3, 4, 5).stream() .collect(Collectors.toSet()) // 1, 2, 3, 4, 5 .forEach(System.out :: println); 复制代码
sorted
======
-
sorted方法根据自然排序返回Stream流
-
sorted(Comparator comparator)方法根据提供的Comparator进行排序
/*
- 使用sorted方法实现min求最小值和max求最大值
*/
List list = Arrays.asList(1, 2, 3, 4, 5);
// 数字的自然排序就是从小到大
Optional min = list.stream().sorted().findFirst();
System.out.println(min :: get());
Optional max = list.stream.sorted((a, b) -> b - a).findFirst();
System.out.println(max :: get());
/*
- 按照字母顺序a - z排序
*/
Arrays.asList(“java”, “python”, “c”).stream().sorted().forEach(System.out :: println);
/*
- 按照字母的长度进行排序
*/
Arrays.asList(“java”, “python”, “c”).stream().sorted((a, b) -> a.length() - b.length()).forEach(System.out :: println);
limit
=====
-
limit方法用来截取指定长度的Stream流
-
skip方法用来丢弃指定长度的流数据,可以与limit配合实现分页
/*
- 打印出集合中20 - 30的数据
*/
Stream.iterate(x -> x + 1).limit(50)
// 跳过前20个
.skip(20)
// 输出20 - 30
.forEach(System.out :: println);
map
===
-
map用来将Stream流中的元素按照指定的函数映射成一个新的元素的Stream流
-
flatMap用来将Stream流中的每个元素转换成另一个流,然后将所有流连接成一个新的流
List list = Arrays.asList(“a, b, c”, “1, 2, 3”);
/*
- 将字符串转换为不带逗号的元素
*/
Stream mapList = list.stream().map(s -> s.replace(“,”, “”));
// abc 123
mapList.forEach(System.out :: println);
Stream flatMapList = list.stream().flatMap(s -> {
// 将每一个元素转换为流数据
String[] arrayStr = s.split(“,”);
Stream stream = Arrays.stream(arrayStr);
return stream;
});
// a b c 1 2 3
flatMapList.forEach(System.out :: println);
peek
====
- peek方法用来获取Stream流中的每一个元素 类似于map, 但是map中接收的是一个Function表达式,有返回值 peek中接收的是一个Consumer表达式,没有返回值
String str = “11, 22, 33, 44, 55”;
// 11 22 33 44 55 165
System.out.println(Stream.of(str.split(“,”)).peek(System.out :: println).mapToInt(Integer :: valueOf).sum());
终止操作
====
循环-forEach
==========
- forEach用来循环遍历每一个元素
// 创建一个实体类,包含有一个属性为num属性.并且有一个build()方法用于为num赋值
String str = “1, 2, 3”
/*
- 输出 num = 1, num = 2, num = 3
*/
Stream.of(str.split(“,”)).map(x -> new User(x)).forEach(System.out :: println);
Stream.of(str.split(“,”)).map(User :: new).forEach(System.out :: println);
Stream.of(str.split(“,”)).map(x -> User.build(x)).forEach(System.out :: println);
Stream.of(str.split(“,”)).map(User :: build).forEach(System.out :: println);
计算-min,max,count,sum
====================
-
min: 返回Stream流元素中的最小值
-
max: 返回Stream流元素中的最大值
-
count: 返回Stream流元素中的总个数
-
sum: 对Stream流元素进行求和
List list = Arrays.asList(1, 2, 3, 4, 5, 6);
// 求集合的最大值 - 6
System.out.println(list.stream().max((a, b) -> a - b).get());
// 求集合的最小值 - 1
System.out.println(list.stream().min((a, b) -> a - b).get());
// 统计元素的个数 - 6
System.out.println(list.stream().count());
// 元素求和
String str = “11, 22, 33, 44, 55”;
System.out.println(Stream.of(str.split(“,”)).mapToInt(x -> Integer.valueOf(x)).sum());
System.out.println(Stream.of(str.split(“,”)).mapToInt(Integer :: valueOf).sum());
System.out.println(Stream.of(str.split(“,”)).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum());
System.out.println(Stream.of(str.split(“,”)).map(Integer :: valueOf).mapToInt(x -> x).sum());
匹配-anyMatch,allMatch,noneMatch,findFirst,findAny
================================================
-
anyMatch: 接收一个Predicate函数,只要Stream流中有一个元素满足该断言则返回true, 否则返回false
-
allMatch: 接收一个Predicate函数,当Stream流中每一个元素都满足该断言则返回true, 否则返回false
-
noneMatch: 接收一个Predicate函数,当Stream流中每一个元素都不符合该断言则返回true, 否则返回false
-
findFirst: 返回Stream流中的第一个元素
-
findAny: 返回Stream流中的任意一个元素
List list = Arrays.asList(1, 2, 3, 4, 5, 6);
// 如果集合的元素都大于等于0则返回true
System.out.println(list.stream().allMatch(x -> x >= 0));
// 如果集合中有大于5的元素,返回false
Systemm.out.println(list.stream().noneMatch(x -> x > 5));
// 如果集合中有大于3的元素则返回true
System.out.println(list.stream().anyMatch(x -> x > 3));
// 取第一个偶数
System.out.println(list.stream().filter(x -> x % 2 == 0).findFirst().get());
// 取任意一个偶数
System.out.println(list.stream().filter(x -> x % 2 == 0).findAny().get());
收集器-toArray,collect
===================
-
collect: 接收一个Collector实例,将流中元素转变为另外一种数据结构
-
Collector<T, A, R> 是一个接口,包含5个抽象方法: Supplier< A > supplier(): 创建一个结果容器 BiConsumer<A, T> accumulator(): 消费型接口. 第一个参数为容器A, 第二个参数为流中元素T BinaryOperator< A > combiner(): 函数接口. 该函数的作用是将各个子流程的运行结果,即accumulator函数操作后的容器A进行合并 Function<A, R> finisher(): 函数式接口. 参数为容器A, 返回类型为collect方法需要的结果类型R Set< Chracteristics > characteristics(): 返回一个不可变的Set集合,用来表明该Collector的特性
// 将对象值转化为List
List ageList = userList.stream().map(User :: getAge).collect(Collectors.toList());
// 将对象值转化为Set
Set ageSet = userList.stream().map(User :: getAge).collect(Collectors.toMap());
// 将对象值转换为Map. 要求key的取值不能相同
Map<String, Integer> userMap = userList.stream().collect(Colletors.toMap(User :: getName, User :: getAge));
// 字符串分隔符连接
String joinName = userList.stream().map(User :: getName).collect(Collectors.join(“,”, “(”, “)”))
// 聚合操作 - 计算对象总数
Long count = userList.stream().collect(Collectors.counting());
// 聚合操作 - 计算最大值
Integer maxAge = userList.stream().map(User :: getAge).collect(Collectors.maxBy(Integer :: compare)).get();
// 聚合操作 - 计算对象值总数
Integer sumAge = userList.stream().collect(Collectors.summingInt(User :: getAge));
// 聚合操作 - 计算对象值的平均数
Double averageAge = userList.stream().collet(Collectors.averagingDouble(User :: getAge));
// 根据Age分组
Map<Integer, List> ageMap = userList.stream().collect(Collectors.groupingBy(User :: getAge));
// 根据条件分区: 一部分大于10, 一部分小于10
Map<Boolean, List> partMap = userList.stream().collect(Collectors.partitionBy(x -> x.getAge() > 10));
// 规约
Integer value = userList.stream().map(User :: getAge).collect(Collectors.reducing(Integer :: sum)).get();
parallelStream
==============
- parallelStream是流并行处理程序的代替方法
List strings = Arrays.asList(“I”, “want”, “to”, “be”, “”, “great”);
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
- 可以很容易的在顺序运行和并行之间进行直接切换
Collectors
==========
-
Collectors类实现很多归约操作,比如将流转换成集合和聚合元素
-
Collectors可用于返回列表和字符串
List strings = Arrays.asList(“I”, “want”, “to”, “be”, “”, “great”);
// 过滤掉空字符串
List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
// 合并字符串
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(“,”));
averagingDouble
===============
/**
-
返回一个Collector,生成应用于输入元素double值函数的算术平均值
-
结果可能会存在误差
-
@param mapper 获取需要计算算数平均值的值的映射器
-
@return Collector<T, ?, Double> 计算算术平均值的Collector
*/
public static Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper) {
/*
-
在收集操作的数组中:
-
索引0 - 运行总和的高位
-
索引1 - 补偿计算总和的低位
-
索引2 - 可见值的数量
*/
return new CollectorImpl<>(
() -> new double[4],
(a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;},
(a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
CH_NOID);
}
averagingInt
============
/**
-
返回一个Collector,生成应用于输入元素int值函数的算术平均值
-
@param mapper 获取需要计算算数平均值的值的映射器
-
@return Collector<T, ?, Double> 计算算术平均值的Collector
*/
public static Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper) {
return new CollectorImpl<>(
() -> new long[2],
(a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
}
averagingLong
=============
/**
-
返回一个Collector,生成应用于输入元素long值函数的算术平均值
-
@param mapper 获取需要计算算数平均值的值的映射器
-
@return Collector<T, ?, Double> 计算算术平均值的Collector
*/
public static Collector<T, ?, Double> averagingLong(ToLongFunction<? super T> mapper) {
return new CollectorImpl<>(
() -> new long[2],
(a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
}
collectingAndThen
=================
/**
-
调整Collector进行额外的转换
-
@param downstream 生成的下游收集器
-
@param finisher 额外执行的操作
-
@return Collector<T,A,RR> 进行额外操作的下游收集器
*/
public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) {
Set<Collector.Characteristics> characteristics = downstream.characteristics();
if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
if (characteristics.size() == 1)
characteristics = Collectors.CH_NOID;
else {
characteristics = EnumSet.copyOf(characteristics);
characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
characteristics = Collections.unmodifiableSet(characteristics);
}
}
return new CollectorImpl<>(downstream.supplier(),
downstream.accumulator(),
downstream.combiner(),
downstream.finisher().andThen(finisher),
characteristics);
}
counting
========
/**
-
返回Collector中指定类型元素的数量
-
@return Collector<T, ?, Long> 指定输入元素数量的收集器
*/
public static Collector<T, ?, Long> counting() {
return summingLong(e -> 1L);
}
groupingBy
==========
/**
-
返回一个对输入的指定类型的元素执行分组操作的Collector
-
- 根据分组函数进行分组操作
-
- 并将结果以Map类型返回
-
@param classifier 指定的分组函数
-
@return Collector<T, ?, Map<K, List>> Map类型的返回结果
*/
public static <T, K> Collector<T, ?, Map<K, List>> groupingBy(Function<? super T, ? extends K> classifier) {
return groupingBy(classifier, toList());
}
/**
-
返回一个对输入的指定类型的元素执行级联分组操作的Collector
-
- 根据分组函数进行分组操作
-
- 然后根据下游收集器对关联key的value值执行指定的规约操作
-
@param classifier 指定的分组函数
-
@param downstream 指定执行规约操作的下游收集器
-
@return Collector<T, ?, Map<K, D>> 实现了级联分组操作的结果
*/
public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream) {
return groupingBy(classifier, HashMap::new, downstream);
}
/**
-
返回一个对输入的指定类型的元素执行级联分组操作的,并以指定的Map实现方式保存结果返回的Collector
-
- 根据分组函数进行分组操作
-
- 再根据下游收集器对关联key的value值执行指定的规约操作
-
- 然后将结果保存到指定方式实现的Map中
-
@param classifier 指定的分组函数
-
@param mapFactory 指定的Map实现
-
@param downstream 指定执行规约操作的下游收集器
-
@return Collector<T, ?, M> 实现了级联分组操作的Collector结果
*/
public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier mapFactory, Collector<? super T, A, D> downstream) {
Supplier downstreamSupplier = downstream.supplier();
BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
K key = Objects.requireNonNull(classifier.apply(t), “element cannot be mapped to a null key”);
A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
downstreamAccumulator.accept(container, t);
};
BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
@SuppressWarnings(“unchecked”)
Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
}
else {
@SuppressWarnings(“unchecked”)
Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
Function<Map<K, A>, M> finisher = intermediate -> {
intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
@SuppressWarnings(“unchecked”)
M castResult = (M) intermediate;
return castResult;
};
return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
}
}
groupingByConcurrent
====================
/**
-
返回一个对输入的指定类型的元素执行分组操作的并行Collector
-
- 根据分组函数进行分组操作
-
- 并将结果以Map类型返回
-
@param classifier 指定的分组函数
-
@return Collector<T, ?, ConcurrentMap<K, List>> 实现分组操作的并发无序的Collector
*/
public static <T, K> Collector<T, ?, ConcurrentMap<K, List>> groupingByConcurrent(Function<? super T, ? extends K> classifier) {
return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList());
}
/**
-
返回一个对输入的指定类型的元素执行级联分组操作的并行Collector
-
- 根据分组函数进行分组操作
-
- 然后根据下游收集器对关联key的指定value值执行指定的规约操作
-
@param classifier 指定的分组函数
-
@downstream 指定执行规约操作的下游收集器
-
@return Collector<T, ?, ConcurrentMap<K, D>> 实现分组操作的并发无序的Collector
*/
public static <T, K, A, D> Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream) {
return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
}
/**
-
返回一个对输入的指定类型的元素执行级联分组操作的并行Collector
-
- 根据分组函数进行分组操作
-
- 再根据下游收集器对关联key的指定value值执行指定的规约操作
-
- 然后将结果保存到指定方式实现的Map中
-
@param classifier 指定的分组函数
-
@param mapFactory 指定的Map实现
-
@downstream 指定执行规约操作的下游收集器
-
@return Collector<T, ?, ConcurrentMap<K, D>> 实现分组操作的并发无序的Collector
*/
public static <T, K, A, D, M extends ConcurrentMap<K, D>> Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier, Supplier mapFactory, Collector<? super T, A, D> downstream) {
Supplier downstreamSupplier = downstream.supplier();
BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
BinaryOperator<ConcurrentMap<K, A>> merger = Collectors.<K, A, ConcurrentMap<K, A>>mapMerger(downstream.combiner());
@SuppressWarnings(“unchecked”)
Supplier<ConcurrentMap<K, A>> mangledFactory = (Supplier<ConcurrentMap<K, A>>) mapFactory;
BiConsumer<ConcurrentMap<K, A>, T> accumulator;
if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) {
accumulator = (m, t) -> {
K key = Objects.requireNonNull(classifier.apply(t), “element cannot be mapped to a null key”);
A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
downstreamAccumulator.accept(resultContainer, t);
};
}
else {
accumulator = (m, t) -> {
K key = Objects.requireNonNull(classifier.apply(t), “element cannot be mapped to a null key”);
A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
synchronized (resultContainer) {
downstreamAccumulator.accept(resultContainer, t);
}
};
}
if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_CONCURRENT_ID);
}
else {
@SuppressWarnings(“unchecked”)
Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
Function<ConcurrentMap<K, A>, M> finisher = intermediate -> {
intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
@SuppressWarnings(“unchecked”)
M castResult = (M) intermediate;
return castResult;
};
return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_CONCURRENT_NOID);
}
}
joining
=======
/**
-
返回一个根据接收元素的顺序将元素连接成一个String字符串的Collector
-
@return Collector<CharSequence, ?, String> 根据接收元素的顺序将元素连接成一个字符串的Collector
*/
public static Collector<CharSequence, ?, String> joining() {
return new CollectorImpl<CharSequence, StringBuilder, String>(
StringBuilder::new, StringBuilder::append,
(r1, r2) -> { r1.append(r2); return r1; },
StringBuilder::toString, CH_NOID);
}
/**
-
返回一个根据接收元素的顺序将元素连接成一个String字符串并以指定的分隔符分割的Collector
-
@param delimiter 用于每个元素之间的分割符
-
@return Collector<CharSequence, ?, String> 根据接收元素的顺序将元素连接成一个字符串并以指定分割符分割的Collector
*/
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
return joining(delimiter, “”, “”);
}
/**
-
返回一个根据接收元素的顺序将元素连接成一个String字符串并以指定的分隔符分割和指定前缀和后缀的Collector
-
@param delimiter 用于每个元素之间的分割符
-
@param prefix 指定的前缀
-
@param suffix 指定的后缀
-
@return Collector<CharSequence, ?, String> 根据接收元素的顺序将元素连接成一个字符串并以指定分割符分割和指定的前缀和后缀的Collector
*/
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
return new CollectorImpl<>(
() -> new StringJoiner(delimiter, prefix, suffix),
StringJoiner::add, StringJoiner::merge,
StringJoiner::toString, CH_NOID);
}
mapping
=======
/**
-
在累积元素之前应用映射函数将类型为U的收集器调整为类型为T的收集器
-
mapping操作对多级规约操作最有用
-
@param mapper 映射函数
-
@param downstream 下游收集器
-
@return Collector<T, ?, R> 执行映射函数操作后的收集器
*/
public static <T, U, A, R> Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
return new CollectorImpl<>(downstream.supplier(),
(r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
downstream.combiner(), downstream.finisher(),
downstream.characteristics());
}
maxBy
=====
/**
-
返回一个根据给定的比较器Comparator生成最大元素的Collector,使用Optional描述
-
@param comparator 指定的比较器
-
@return Collector<T, ?, Optional> 根据比较器生成最大元素的Collector
*/
public static Collector<T, ?, Optional> maxBy(Comparator<? super T> comparator) {
return reducing(BinaryOperator.maxBy(comparator));
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后
终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化
的比较器Comparator生成最大元素的Collector,使用Optional描述
-
@param comparator 指定的比较器
-
@return Collector<T, ?, Optional> 根据比较器生成最大元素的Collector
*/
public static Collector<T, ?, Optional> maxBy(Comparator<? super T> comparator) {
return reducing(BinaryOperator.maxBy(comparator));
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-xTtISKGT-1711639175166)]
[外链图片转存中…(img-83UhUMGU-1711639175167)]
[外链图片转存中…(img-TVgqcZOO-1711639175167)]
[外链图片转存中…(img-Hq56IwCS-1711639175167)]
[外链图片转存中…(img-c80rSD4l-1711639175168)]
[外链图片转存中…(img-fhBo8dZg-1711639175168)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-IdzkRQ6m-1711639175168)]
最后
终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化
[外链图片转存中…(img-ji1wNKdM-1711639175169)]