private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
public static void distinct() {
List<String> strings = List.of("2", "2", "2", "1" , "2", "3", "4", "5", "6");
System.err.println("-----------------");
System.err.println(strings.stream());
System.err.println(strings.stream().count());
System.err.println(strings.stream().findAny().get());
System.err.println(strings.stream().findFirst().get());
System.err.println("-----------------");
System.err.println(strings.stream().collect(Collectors.joining()));
System.err.println(strings.stream().collect(Collectors.joining(",")));
System.err.println(strings.stream().collect(Collectors.joining(",", "{", "}")));
System.err.println("-----------------toMap");
//使用Function.identity()如果遇到重复key会报错。
//System.err.println(strings.stream().collect(Collectors.toMap(v -> v,Function.identity())));
System.err.println(strings.stream().collect(Collectors.toMap(v -> v, dto -> dto, (olds, news) -> news)));
System.err.println("-----------------统计出现个数");
System.err.println(strings.stream().collect(Collectors.groupingBy(num -> num, Collectors.counting())));
System.err.println("-----------------排序,正序");
System.err.println(strings.stream().sorted().collect(Collectors.joining()));
System.err.println("-----------------排序,逆序");
System.err.println(strings.stream().sorted(Comparator.reverseOrder()).collect(Collectors.joining()));
System.err.println("-----------------排序,自定义规则");
System.err.println(strings.stream().sorted(Comparator.comparing(m -> "asd" + m, Comparator.reverseOrder())).collect(Collectors.joining()));
System.err.println("-----------------偷瞄");
System.err.println(strings.stream().filter(d -> Objects
.equals("2", d))
.peek(d -> System.err.print(d + ","))
.collect(Collectors.joining()));
/*
1.Instant.now():通过这种方式获取的时间戳与北京时间相差8个时区,需要修正为北京时间,
通过查看源代码发现Instant.now()使用等是UTC时间Clock.systemUTC().instant()。LocalDate、LocalDateTime 的now()方法使用的是系统默认时区 不存在Instant.now()的时间问题。
2..stream() 串行流,当前线程按顺序执行。
3..stream().parallel() 并行流,使用ForkJoinPool框架并行执行代码,不能保证顺序。
4..stream().parallel().forEachOrdered() 最终是串行执行,使用ForkJoinPool中的某一个线程串行执行,forEachOrdered中的代码。
用并行流需要避免去访问公共资源,最好使用collect()去构建新集合。
*/
System.err.println("-----------------普通流,串行执行");
strings.stream().forEach(d -> {
Consumer c = System.err::println;
c.accept(Thread.currentThread().getName() + ":" + d + ":" + Instant.now().getEpochSecond());
try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); }
});
System.err.println("-----------------并行流,可通过启动参数设置worker的数量 -Djava.util.concurrent.ForkJoinPool.common.parallelism=N \n");
strings.stream().parallel().forEach(d -> {
Consumer c = System.err::println;
c.accept(Thread.currentThread().getName() + ":" + d + ":" + Instant.now().getEpochSecond());
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
});
System.err.println("-----------------forEachOrdered,并行执行后,再按顺序处理");
strings.stream().parallel().forEachOrdered(d -> {
Consumer c = System.err::println;
c.accept(Thread.currentThread().getName() + ":" + d + ":" + Instant.now().getEpochSecond());
try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); }
});
System.err.println("-----------------sequential:从并行流转换为顺序流,这是个中间操作");
System.err.println("default -> " + strings.stream().isParallel());
System.err.println("sequential -> " + strings.stream().sequential().isParallel());
System.err.println("parallel -> " + strings.stream().parallel().isParallel());
System.err.println("-----------------Limit");
strings.stream().limit(2).forEach(System.err::print);
System.err.println("---------------------------------------------------");
System.err.println();
System.err.println("-----------------allMatch,全部符合条件");
System.err.println(strings.stream().allMatch(d -> "2".equals(d)));
System.err.println("-----------------anyMatch,只需要一个符合条件");
System.err.println(strings.stream().anyMatch(d -> "2".equals(d)));
System.err.println("-----------------noneMatch,没有一个符合条件");
System.err.println(strings.stream().noneMatch(d -> "2".equals(d)));
System.err.println("---------------------------------------------------");
/**
* 2,2,2,1,3,2,2
* dropWhile(n -> n == 2)
* @retrun 1,3,2,2
*
* 2,2,2,1,3,2,2
* takeWhile(n -> n == 2)
* @retrun 2,2,2
*
*/
System.err.println("-----------------dropWhile,API的dropWhile()方法丢弃所有值,直到谓词 返回false为止,后面就算匹配也不处理");
System.err.println(strings.stream().dropWhile(x -> Integer.valueOf(x) == 2).collect(Collectors.toList()));
System.err.println("-----------------takeWhile,API的takeWhile() 方法接受所有值,直到谓词 返回false为止,后面就算匹配也不处理");
System.err.println(strings.stream().takeWhile(x -> Integer.valueOf(x) == 2).collect(Collectors.toList()));
System.err.println("-----------------max");
strings.stream().max(Comparator.naturalOrder()).ifPresent(System.err::println);
System.err.println("-----------------min");
strings.stream().min(Comparator.naturalOrder()).ifPresent(((Consumer)System.err::println).andThen(d -> System.err.println("----------------------")));
System.err.println("----------------------reduce");
Stream.of(1, 2, 3, 4, 1).reduce((acc, item) -> {
System.out.print("acc : " + acc);
System.out.print(" item: " + item);
System.out.println(" new_acc : " + (acc += item));
return acc;
}).ifPresent(((Consumer)System.err::println).andThen(d -> System.err.println("----------------------reduce")));
}
D:\job\jdk-11.0.7\bin\java.exe "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2020.3.3\lib\idea_rt.jar=55382:D:\Program Files\JetBrains\IntelliJ IDEA 2020.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\code\leetcode\target\classes;E:\storage\org\springframework\boot\spring-boot-starter\2.4.4\spring-boot-starter-2.4.4.jar;E:\storage\org\springframework\boot\spring-boot\2.4.4\spring-boot-2.4.4.jar;E:\storage\org\springframework\spring-context\5.3.5\spring-context-5.3.5.jar;E:\storage\org\springframework\boot\spring-boot-autoconfigure\2.4.4\spring-boot-autoconfigure-2.4.4.jar;E:\storage\org\springframework\boot\spring-boot-starter-logging\2.4.4\spring-boot-starter-logging-2.4.4.jar;E:\storage\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;E:\storage\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;E:\storage\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;E:\storage\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;E:\storage\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;E:\storage\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;E:\storage\org\springframework\spring-core\5.3.5\spring-core-5.3.5.jar;E:\storage\org\springframework\spring-jcl\5.3.5\spring-jcl-5.3.5.jar;E:\storage\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;E:\storage\org\springframework\boot\spring-boot-starter-web\2.4.4\spring-boot-starter-web-2.4.4.jar;E:\storage\org\springframework\boot\spring-boot-starter-json\2.4.4\spring-boot-starter-json-2.4.4.jar;E:\storage\com\fasterxml\jackson\core\jackson-databind\2.11.4\jackson-databind-2.11.4.jar;E:\storage\com\fasterxml\jackson\core\jackson-annotations\2.11.4\jackson-annotations-2.11.4.jar;E:\storage\com\fasterxml\jackson\core\jackson-core\2.11.4\jackson-core-2.11.4.jar;E:\storage\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.4\jackson-datatype-jdk8-2.11.4.jar;E:\storage\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.4\jackson-datatype-jsr310-2.11.4.jar;E:\storage\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.4\jackson-module-parameter-names-2.11.4.jar;E:\storage\org\springframework\boot\spring-boot-starter-tomcat\2.4.4\spring-boot-starter-tomcat-2.4.4.jar;E:\storage\org\apache\tomcat\embed\tomcat-embed-core\9.0.44\tomcat-embed-core-9.0.44.jar;E:\storage\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;E:\storage\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.44\tomcat-embed-websocket-9.0.44.jar;E:\storage\org\springframework\spring-web\5.3.5\spring-web-5.3.5.jar;E:\storage\org\springframework\spring-beans\5.3.5\spring-beans-5.3.5.jar;E:\storage\org\springframework\spring-webmvc\5.3.5\spring-webmvc-5.3.5.jar;E:\storage\org\springframework\spring-expression\5.3.5\spring-expression-5.3.5.jar;E:\storage\org\springframework\boot\spring-boot-starter-aop\2.4.4\spring-boot-starter-aop-2.4.4.jar;E:\storage\org\springframework\spring-aop\5.3.5\spring-aop-5.3.5.jar;E:\storage\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar;E:\storage\com\google\guava\guava\30.1.1-jre\guava-30.1.1-jre.jar;E:\storage\com\google\guava\failureaccess\1.0.1\failureaccess-1.0.1.jar;E:\storage\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;E:\storage\com\google\code\findbugs\jsr305\3.0.2\jsr305-3.0.2.jar;E:\storage\org\checkerframework\checker-qual\3.8.0\checker-qual-3.8.0.jar;E:\storage\com\google\errorprone\error_prone_annotations\2.5.1\error_prone_annotations-2.5.1.jar;E:\storage\com\google\j2objc\j2objc-annotations\1.3\j2objc-annotations-1.3.jar;E:\storage\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar com.casa.leetcode.stream.Distinct
-----------------
java.util.stream.ReferencePipeline$Head@5d624da6
9
2
2
-----------------
222123456
2,2,2,1,2,3,4,5,6
{2,2,2,1,2,3,4,5,6}
-----------------toMap
{1=1, 2=2, 3=3, 4=4, 5=5, 6=6}
-----------------统计出现个数
{1=1, 2=4, 3=1, 4=1, 5=1, 6=1}
-----------------排序,正序
122223456
-----------------排序,逆序
654322221
-----------------排序,自定义规则
654322221
-----------------偷瞄
2,2,2,2,2222
-----------------普通流,串行执行
main:2:1625126462
main:2:1625126462
main:2:1625126462
main:1:1625126462
main:2:1625126462
main:3:1625126462
main:4:1625126462
main:5:1625126462
main:6:1625126462
-----------------并行流,可通过启动参数设置worker的数量 -Djava.util.concurrent.ForkJoinPool.common.parallelism=N
main:3:1625126462
ForkJoinPool.commonPool-worker-7:2:1625126462
ForkJoinPool.commonPool-worker-9:4:1625126462
ForkJoinPool.commonPool-worker-3:2:1625126462
ForkJoinPool.commonPool-worker-5:5:1625126462
ForkJoinPool.commonPool-worker-11:1:1625126462
ForkJoinPool.commonPool-worker-7:2:1625126463
ForkJoinPool.commonPool-worker-5:6:1625126463
ForkJoinPool.commonPool-worker-3:2:1625126463
-----------------forEachOrdered,并行执行后,再按顺序处理
ForkJoinPool.commonPool-worker-11:2:1625126463
ForkJoinPool.commonPool-worker-11:2:1625126463
ForkJoinPool.commonPool-worker-11:2:1625126463
ForkJoinPool.commonPool-worker-11:1:1625126463
ForkJoinPool.commonPool-worker-11:2:1625126463
ForkJoinPool.commonPool-worker-11:3:1625126463
ForkJoinPool.commonPool-worker-11:4:1625126463
ForkJoinPool.commonPool-worker-11:5:1625126463
ForkJoinPool.commonPool-worker-11:6:1625126463
-----------------sequential:从并行流转换为顺序流,这是个中间操作
default -> false
sequential -> false
parallel -> true
-----------------Limit
22---------------------------------------------------
-----------------allMatch,全部符合条件
false
-----------------anyMatch,只需要一个符合条件
true
-----------------noneMatch,没有一个符合条件
false
---------------------------------------------------
-----------------dropWhile,API的dropWhile()方法丢弃所有值,直到谓词 返回false为止,后面就算匹配也不处理
[1, 2, 3, 4, 5, 6]
-----------------takeWhile,API的takeWhile() 方法接受所有值,直到谓词 返回false为止,后面就算匹配也不处理
[2, 2, 2]
-----------------max
6
-----------------min
1
----------------------
----------------------reduce
11
----------------------reduce
acc : 1 item: 2 new_acc : 3
acc : 3 item: 3 new_acc : 6
acc : 6 item: 4 new_acc : 10
acc : 10 item: 1 new_acc : 11
Process finished with exit code 0