java8 array、list操作 汇【3】)(-Java8新特性之Collectors 详解
//编写一个定制的收集器
public static class MultisetCollector<T> implements Collector<T, Multiset<T>, Multiset<T>> { @Override
public Supplier<Multiset<T>> supplier() {
return HashMultiset::create;
} @Override
public BiConsumer<Multiset<T>, T> accumulator() {
return (set, e) -> set.add(e, 1);
} @Override
public BinaryOperator<Multiset<T>> combiner() {
return (set1, set2) -> {
set1.addAll(set2);
return set1;
};
} @Override
public Function<Multiset<T>, Multiset<T>> finisher() {
return Function.identity();
} @Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));
}
} public static void main(String[] args){ /* 转载:https://blog.csdn.net/u013291394/article/details/52662761
git: https://github.com/shekhargulati/java8-the-missing-tutorial/tree/master/code */ List<Task> tasks = DataUtils.getTasks();
Map<TaskType, List<Task>> allTasksByType = new HashMap<>();
for (Task task : tasks) {
List<Task> existingTasksByType = allTasksByType.get(task.getType());
if (existingTasksByType == null) {
List<Task> tasksByType = new ArrayList<>();
tasksByType.add(task);
allTasksByType.put(task.getType(), tasksByType);
} else {
existingTasksByType.add(task);
}
}
for (Map.Entry<TaskType, List<Task>> entry : allTasksByType.entrySet()) {
System.out.println(String.format("%s =>> %s", entry.getKey(), entry.getValue()));
} //生成统计信息
IntSummaryStatistics summaryStatistics = tasks.stream().map(Task::getTitle).collect(summarizingInt(String::length));
System.out.println(summaryStatistics.getAverage()); //32.4
System.out.println(summaryStatistics.getCount()); //
System.out.println(summaryStatistics.getMax()); //
System.out.println(summaryStatistics.getMin()); //
System.out.println(summaryStatistics.getSum()); //162 //编写一个定制的收集器
List<String> names = Arrays.asList("shekhar", "rahul", "shekhar");
Multiset<String> set = names.stream().collect(new MultisetCollector<>()); set.forEach(str -> System.out.println(str + ":" + set.count(str))); } //Java8中的字数统计
public static void wordCount(Path path) throws IOException {
Map<String, Long> wordCount = Files.lines(path)
.parallel()
.flatMap(line -> Arrays.stream(line.trim().split("\\s")))
.map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
.filter(word -> word.length() > 0)
.map(word -> new AbstractMap.SimpleEntry<>(word, 1))
.collect(groupingBy(AbstractMap.SimpleEntry::getKey, counting()));
wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));
} //将数据收集进一个集合
public static Set<String> uniqueTitles(List<Task> tasks) {
return tasks.stream().map(Task::getTitle).collect(toSet());
}
//将数据收集进一个映射
private static Map<String, Task> taskMap(List<Task> tasks) {
return tasks.stream().collect(toMap(Task::getTitle, Function.identity()));
// return tasks.stream().collect(toMap(Task::getTitle, task -> task));
}
//使用toMap方法的另一个变体来处理重复问题,它允许我们指定一个合并方法。这个合并方法允许用户他们指定想如何处理多个值关联到同一个键的冲突。
//在下面展示的代码中,我们只是使用了新的值,当然你也可以编写一个智能的算法来处理冲突。
private static Map<String, Task> taskMap_duplicates(List<Task> tasks) {
return tasks.stream().collect(toMap(Task::getTitle, identity(), (t1, t2) -> t2));
}
//可以通过使用toMap方法的第三个变体来指定其他的映射实现。这需要你指定将用来存储结果的Map和Supplier。
public Map<String, Task> collectToMap(List<Task> tasks) {
return tasks.stream().collect(toMap(Task::getTitle, identity(), (t1, t2) -> t2, LinkedHashMap::new));
}
// list<bean> -> Map<String, String>
public class Person {
private Integer id;
private String name;
} import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream; public class Test {
public static void main(String[] args) { List<Person> list = new ArrayList();
list.add(new Person(1, "haha"));list.add(new Person(2, "rere"));list.add(new Person(3, "fefe")); Map<Integer, Person> mapp = list.stream().collect(Collectors.toMap(Person::getId, Function.identity()));
System.out.println(mapp); System.out.println(mapp.get(1).getName()); Map<Integer, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName));
System.out.println(map); }
}
得到的结果:
{1=test.Person@4b9385, 2=test.Person@1311334, 3=test.Person@2a0b20} haha {1=haha, 2=rere, 3=fefe} 来源: https://blog.csdn.net/jiangpingjiangping/article/details/764740
//使用其它的收集器
//像toList和toSet这类特定的收集器不允许你指定内部的列表或者集合实现。当你想要将结果收集到其它类型的集合中时,你可以像下面这样使用toCollection收集器。
private static LinkedHashSet<Task> collectToLinkedHaskSet(List<Task> tasks) {
return tasks.stream().collect(toCollection(LinkedHashSet::new));
}
//找到拥有最长标题的任务
public Task taskWithLongestTitle(List<Task> tasks) {
return tasks.stream().collect(collectingAndThen(maxBy((t1, t2) -> t1.getTitle().length() - t2.getTitle().length()), Optional::get));
}
//统计标签的总数
public int totalTagCount(List<Task> tasks) {
return tasks.stream().collect(summingInt(task -> task.getTags().size()));
}
//生成任务标题的概述
public String titleSummary(List<Task> tasks) {
return tasks.stream().map(Task::getTitle).collect(joining(";"));
}
//分类收集器
//例子1:根据类型对任务分类
private static Map<TaskType, List<Task>> groupTasksByType(List<Task> tasks) {
return tasks.stream().collect(groupingBy(Task::getType));
//return tasks.stream().collect(groupingBy(task -> task.getType()));
}
//例子2:根据标签分类
private static Map<String, List<Task>> groupingByTag(List<Task> tasks) {
return tasks.stream().
flatMap(task -> task.getTags().stream().map(tag -> new TaskTag(tag, task))).
collect(groupingBy(TaskTag::getTag, mapping(TaskTag::getTask,toList())));
}
//例子3:根据标签和数量对任务分类
private static Map<String, Long> tagsAndCount(List<Task> tasks) {
return tasks.stream().
flatMap(task -> task.getTags().stream().map(tag -> new TaskTag(tag, task))).
collect(groupingBy(TaskTag::getTag, counting()));
}
//例子4:根据任务类型和创建日期分类
private static Map<TaskType, Map<LocalDate, List<Task>>> groupTasksByTypeAndCreationDate(List<Task> tasks) {
return tasks.stream().collect(groupingBy(Task::getType, groupingBy(Task::getCreatedOn)));
}
//分割
private static Map<Boolean, List<Task>> partitionOldAndFutureTasks(List<Task> tasks) {
return tasks.stream().collect(partitioningBy(task -> task.getDueOn().isAfter(LocalDate.now())));
}
//连接所有的标题
private static String allTitles2(List<Task> tasks) {
return tasks.stream().map(Task::getTitle).collect(joining(", "));
}
//将数据收集进一个列表
public static List<String> allTitles(List<Task> tasks) {
return tasks.stream().map(Task::getTitle).collect(toList());
}
public static enum TaskType {
READING, CODING, BLOGGING
}
//bean
public static class Task {
private LocalDate dueOn;
private final String id;
private final String title;
private final String description;
private final TaskType type;
private LocalDate createdOn;
private Set<String> tags = new HashSet<>();
public Task(final String id, final String title, final TaskType type) {
this.id = id;
this.title = title;
this.description = title;
this.type = type;
this.createdOn = LocalDate.now();
}
public Task(final String title, final TaskType type) {
this(title, title, type, LocalDate.now());
}
public Task(final String title, final TaskType type, final LocalDate createdOn) {
this(title, title, type, createdOn);
}
public Task(final String title, final String description, final TaskType type, final LocalDate createdOn) {
this.id = UUID.randomUUID().toString();
this.title = title;
this.description = description;
this.type = type;
this.createdOn = createdOn;
}
public LocalDate getDueOn() {
return dueOn;
}
public void setDueOn(LocalDate dueOn) {
this.dueOn = dueOn;
}
public String getId() {
return id;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public TaskType getType() {
return type;
}
public LocalDate getCreatedOn() {
return createdOn;
}
public Task addTag(String tag) {
this.tags.add(tag);
return this;
}
public Set<String> getTags() {
return Collections.unmodifiableSet(tags);
}
@Override
public String toString() {
return "Task{" +
"title='" + title + '\'' +
", type=" + type +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Task task = (Task) o;
return Objects.equals(title, task.title) &&
Objects.equals(type, task.type);
}
@Override
public int hashCode() {
return Objects.hash(title, type);
}
}
private static class TaskTag {
final String tag;
final Task task;
public TaskTag(String tag, Task task) {
this.tag = tag;
this.task = task;
}
public String getTag() {
return tag;
}
public Task getTask() {
return task;
}
}
public static class DataUtils {
public static Stream<String> lines() {
return filePathToStream("src/main/resources/book.txt");
}
public static Stream<String> negativeWords() {
return filePathToStream("src/main/resources/negative-words.txt");
}
public static Stream<String> filePathToStream(String path) {
try {
return Files.lines(Paths.get("training", path));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static IntStream range(int start, int end) {
return IntStream.rangeClosed(start, end);
}
public static List<Task> getTasks() {
Task task1 = new Task("Read Java 8 in action", TaskType.READING, LocalDate.of(2015, Month.SEPTEMBER, 20)).addTag("java").addTag("java8").addTag("books");
Task task2 = new Task("Write factorial program in Haskell", TaskType.CODING, LocalDate.of(2015, Month.SEPTEMBER, 20)).addTag("program").addTag("haskell").addTag("functional");
Task task3 = new Task("Read Effective Java", TaskType.READING, LocalDate.of(2015, Month.SEPTEMBER, 21)).addTag("java").addTag("books");
Task task4 = new Task("Write a blog on Stream API", TaskType.BLOGGING, LocalDate.of(2015, Month.SEPTEMBER, 21)).addTag("writing").addTag("stream").addTag("java8");
Task task5 = new Task("Write prime number program in Scala", TaskType.CODING, LocalDate.of(2015, Month.SEPTEMBER, 22)).addTag("scala").addTag("functional").addTag("program");
return Stream.of(task1, task2, task3, task4, task5).collect(toList());
}
}
java8 array、list操作 汇【3】)(-Java8新特性之Collectors 详解的更多相关文章
- Swift 3 新特性和迁移详解
写在前面 Swift 3.0 正式版发布了差不多快一个月了,断断续续的把手上和 Swift 相关的迁移到了Swift 3.0.所以写点小总结. 背景 代码量(4万行) 首先,我是今年年初才开始入手 S ...
- IOS6 新特性之UIActivityViewController详解
新的IOS6增加了一些新特性.因为应用需要,所以在国庆的几天里.研究了一下IOS6的说明文档,然后大概地总结了一下UIActivityViewController的用法与大家分享. 首先 从实际效果入 ...
- h5新特性 File API详解
之前一直觉得h5的新特性就是一些新标签呢,直到想研究一下图片上传预览的原理,才发现还是有好多新的api的,只是不兼容ie低版本,挺可惜的, File API在表单中文件输入字段基础上,又添加了一些直接 ...
- Android新特性Instant Run详解
关于 Instant Run Android Studio 2.0 中引入的 Instant Run 是 Run 和 Debug 命令的行为,可以大幅缩短应用更新的时间.尽管首次构建可能需要花费较长的 ...
- [C++11新特性] 智能指针详解
动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极为困难的.有时我们会忘记释放内存产生内存泄漏,有时提前释放了内存,再使用指针去引用内存就会报错. 为了更容易(同时也更安全)地使用动态内存, ...
- Spring Boot 2.3 新特性优雅停机详解
什么是优雅停机 先来一段简单的代码,如下: @RestController public class DemoController { @GetMapping("/demo") p ...
- Java8新特性之Collectors
参考:Java8新特性之Collectors 在第二天,你已经学习了Stream API能够让你以声明式的方式帮助你处理集合.我们看到collect是一个将管道流的结果集到一个list中的结束操作.c ...
- Hadoop 新 MapReduce 框架 Yarn 详解
Hadoop 新 MapReduce 框架 Yarn 详解: http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-yarn/ Ap ...
- C语言操作WINDOWS系统存储区数字证书相关函数详解及实例
C语言操作WINDOWS系统存储区数字证书相关函数详解及实例 以下代码使用C++实现遍历存储区证书及使用UI选择一个证书 --使用CertOpenSystemStore打开证书存储区. --在循环中 ...
随机推荐
- Python的url解析库--urlparse
一.urlparse解析url的query并构建字典 下面的方法主要的功能: 解析url的各个部分,并能够获取url的query部分,并把query部分构建成dict. 具体的代码实现: >&g ...
- codeforces 568a//Primes or Palindromes?// Codeforces Round #315 (Div. 1)
题意:求使pi(n)*q<=rub(n)*p成立的最大的n. 先收集所有的质数和回文数.质数好搜集.回文数奇回文就0-9的数字,然后在头尾添加一个数.在x前后加a,就是x*10+a+a*pow( ...
- 关于"架构"
杨光辉说,在构架系统的早期可能不会更多地考虑架构,主要是在做技术选型,首先是编程语言的选择.对于编程语言选择,当前主流编程语言有很多,有面向对象语言.传统式语言等.做这个选择主要根据人员知识储备,包括 ...
- Connected Components? CodeForces - 920E (bfs)
大意:给定无向图, 求补图的连通块数 bfs模拟即可, 这里用了map存图, set维护未划分的点集, 复杂度$O(nlog^2n)$, 用链表的话可以$O(n)$ #include <iost ...
- 关于floyd 打印路径的问题
我们令 f[i][j] 表示从 i-->j的最短路上j前面的那个点. 显然初始化时 f[i][j]=i; (这样的话先判断一下i是否能到达j好点) 更新条件时,当发现通过点k能使最短 ...
- PaodingAnalysis 提示 "dic home should not be a file, but a directory"
Exception in thread "main" net.paoding.analysis.exception.PaodingAnalysisException: dic ho ...
- IOS UI-滚动视图(UIScrollView)
#import "ViewController.h" /* 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤小是极其有限的,因此直接展示在⽤用户眼前的内容也相当有限 ...
- consumer的DubboClientHandler线程池
1. 创建线程池 创建线程池的调用栈如下: SimpleDataStore把线程池存放在map中. public class NettyClient extends AbstractClient { ...
- Dos命令下目录操作
Dos命令下目录操作 1.cd 操作 显示当前目录名或改变当前目录 cd [盘符][路径] 进入指定盘符下的目录 cd [..] ...
- 跟我一起学习ASP.NET 4.5 MVC4.0(五)
前面几篇文章介绍了一下ASP.NET MVC中的一些基础,今天我们一起来学习一下在ASP.NET MVC中控件的封装.在页面中我们会经常使用到Html对象,来程序控件,当然这里的控件不是说ASP.NE ...