//编写一个定制的收集器
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());
}
}