我正在使用Java 8 lambdas并希望Collectors
toMap
用来返回一个SortedMap
.我能想出的最好的是调用下面Collectors
toMap
用假设法mergeFunction
和mapSupplier
等于TreeMap::new
.
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator = (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
Run Code Online (Sandbox Code Playgroud)
我不想传递合并函数,正如我想要throwingMerger()
的那样,与基本toMap
实现相同,如下所示:
public static <T, K, U>
Collector<T, ?, Map<K, U>> toMap(Function<? …
Run Code Online (Sandbox Code Playgroud) 采取以下示例代码行:
Set<String> someSet = someColletion.stream().map(p -> p.toString()).collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)
我想要一个HashSet
.把调试器带到代码中,我确实得到了一个HashSet
.我看了看java.util.stream.Collectors.toSet()
下面的代码:
public static <T> Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
(left, right) -> { left.addAll(right); return left; },
CH_UNORDERED_ID);
}
Run Code Online (Sandbox Code Playgroud)
合同保证 a Set
,实施决定a HashSet
; 看似合理.但是,我的实现需要由a保证的恒定时间查找HashSet
,而不仅仅是任何旧的查找Set
.如果执行toSet()
决定使用say a FooSet
,这完全在其权利范围内,那么我的实现就会受到影响.
这个问题的最佳实践解决方案是什么?
我正在开发一款在 Java 16 上运行的 Jetty Web 应用程序。我尝试将其升级到 Java 17,但完全由一次调用parallelStream()
.
唯一的变化是 Java 版本从 16 提升到 17,--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED
运行时openjdk:16.0.1-jdk-oraclelinux8
从openjdk:17.0.1-jdk-oraclelinux8
.
我们设法获得了一个线程转储,其中包含许多内容:
"qtp1368594774-200" #200 prio=5 os_prio=0 cpu=475.94ms elapsed=7189.65s tid=0x00007fd49c50cc10 nid=0xd1 waiting on condition [0x00007fd48fef7000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@17.0.1/Native Method)
- parking to wait for <0x00000007b73439a8> (a java.util.stream.ReduceOps$ReduceTask)
at java.util.concurrent.locks.LockSupport.park(java.base@17.0.1/LockSupport.java:341)
at java.util.concurrent.ForkJoinTask.awaitDone(java.base@17.0.1/ForkJoinTask.java:468)
at java.util.concurrent.ForkJoinTask.invoke(java.base@17.0.1/ForkJoinTask.java:687)
at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(java.base@17.0.1/ReduceOps.java:927)
at java.util.stream.AbstractPipeline.evaluate(java.base@17.0.1/AbstractPipeline.java:233)
at java.util.stream.ReferencePipeline.collect(java.base@17.0.1/ReferencePipeline.java:682)
at com.stackoverflowexample.aMethodThatDoesBlockingIOUsingParallelStream()
Run Code Online (Sandbox Code Playgroud)
导致问题的代码类似于:
list.parallelStream()
.map(this::callRestServiceToGetSomeData)
.collect(Collectors.toUnmodifiableList());
Run Code Online (Sandbox Code Playgroud)
此图显示了从 jdk16(左轴)升级到 jdk17(中间的巨大尖峰),然后删除对parallelStream()
仍然在 jdk17(右轴)上的调用之前的线程使用情况:
Java 17 (openjdk-17.0.1_linux-x64_bin.tar.gz) …
我想借此List<Pojo>
和return
一个Map<String, List<Pojo>>
其中Map
的关键是String
价值Pojo
,让我们把它String key
.
澄清一下,给出以下内容:
Pojo 1:Key:值:1
Pojo 2:Key:值:2
Pojo 3:键:b值:3
Pojo 4:键:b值:4
我想要一个Map<String, List<Pojo>>
与keySet()
大小的2,其中键"a"具有的POJO 1和2,和键"b"具有的POJO 3和4.
我怎样才能使用Java 8 lambdas最好地实现这一目标?
当从实例方法返回没有引用其封闭类的匿名类时,它会引用this
.为什么?
请考虑以下代码:
package so;
import java.lang.reflect.Field;
public class SOExample {
private static Object getAnonymousClassFromStaticContext() {
return new Object() {
};
}
private Object getAnonymousClassFromInstanceContext() {
return new Object() {
};
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
Object anonymousClassFromStaticContext = getAnonymousClassFromStaticContext();
Object anonymousClassFromInstanceContext = new SOExample().getAnonymousClassFromInstanceContext();
Field[] fieldsFromAnonymousClassFromStaticContext = anonymousClassFromStaticContext.getClass().getDeclaredFields();
Field[] fieldsFromAnonymousClassFromInstanceContext = anonymousClassFromInstanceContext.getClass().getDeclaredFields();
System.out.println("Number of fields static context: " + fieldsFromAnonymousClassFromStaticContext.length);
System.out.println("Number of fields instance context: " + fieldsFromAnonymousClassFromInstanceContext.length);
System.out.println("Field from instance context: " …
Run Code Online (Sandbox Code Playgroud) 以下代码创建一个Collector
产生UnmodifiableSortedSet
:
package com.stackoverflow;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collector;
import java.util.stream.Collectors;
public class SOExample {
public static <T extends Comparable<T>> Collector<T, ?, SortedSet<T>> toSortedSet() {
return Collectors.toCollection(TreeSet::new);
}
public static <T extends Comparable<T>> Collector<T, ?, SortedSet<T>> toUnmodifiableSortedSet() {
return Collectors.collectingAndThen(toSortedSet(), Collections::<T> unmodifiableSortedSet);
}
}
Run Code Online (Sandbox Code Playgroud)
代码在ecj编译器下编译:
$ java -jar ~/Downloads/ecj-3.13.101.jar -source 1.8 -target 1.8 SOExample.java
Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
Run Code Online (Sandbox Code Playgroud)
但是在javac下:
$ javac -version
Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
javac 1.8.0_73
$ javac SOExample.java
Picked …
Run Code Online (Sandbox Code Playgroud) 我cglib
在 Maven 项目中有一个传递依赖项。尽管添加了我认为正确的内容,但--add-opens
我无法让库与 Java 16 一起使用。
如何开始cglib
使用 Java 16?我在github页面上提出了这个问题。
最小可重现示例:
Main.java
import net.sf.cglib.proxy.Enhancer;
public class Main {
public static void main(String[] args) {
new Enhancer();
}
}
Run Code Online (Sandbox Code Playgroud)
使用 Java 15:
javac -cp cglib-3.3.0.jar Main.java
java --add-opens java.base/java.lang=ALL-UNNAMED -cp cglib-3.3.0.jar:asm-7.1.jar:. Main
Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.sf.cglib.core.ReflectUtils$1 (file:/Users/rbain/Desktop/cglib-3.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of …
Run Code Online (Sandbox Code Playgroud) 我有一个pojos列表,我想要执行一些分组.就像是:
public class Pojo {
private final Category category;
private final BigDecimal someValue;
}
public class Category {
private final String majorCategory;
private final String minorCategory;
}
Run Code Online (Sandbox Code Playgroud)
我想Map<String, Map<String, List<Pojo>>>
,其中的关键是majorCategory
和值是Map
与关键minorCategory
和值是List
中Pojo
的对象表示minorCategory
.
我打算用Java 8 lambdas来实现这一点.我可以通过以下方式完成第一级分组:
Map<String, Pojo> result = list
.stream()
.collect(groupingBy(p -> p.getCategory().getMajorCategory()));
Run Code Online (Sandbox Code Playgroud)
我怎么能再次分组minorCategory
并获得Map<String, Map<String, List<Pojo>>>
我的愿望?
更新
提供的第一个答案对于最初提供的示例是正确的,但是我已经更新了问题.鲁本在接受的答案中的评论提供了最后一块拼图.
假设我有class
哪些implements
java.util.function.Function
.在Function
需要了解的开始日期和结束日期,但这些将是整个函数的生存期内保持不变.
我正在考虑为开始日期和结束日期实现Function
with private final
字段,因为该apply
方法不需要为每个调用使用新值.我觉得这将简化我的实现,但担心这违背了整个函数式编程范例.
Function
在apply
方法需要值但在整个生命周期内保持不变的情况下,使用不可变类成员是否合理 Function
?
filter(Predicate<? super T> predicate)
在Java 8 lambda表达式中使用调用时,我有两种想法,即是否将所有Predicate
逻辑放在一个调用中,或者链接filter(Predicate<? super T> predicate)
调用以在适当的时候提供可读性.
我认为链接filter(Predicate<? super T> predicate)
调用会很便宜,因为他们还没有遇到终结符,所以在可读性方面会犯错,但我对Streams
API的了解不够充分,无法完全理解权衡取舍的内容.
借助以下示例(考虑更复杂的谓词),哪种实现更优越:List<Person> usingOneFilter
或List<Person> usingTwoFilters
?
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SEExample {
private static class Person {
private final int age;
private final int heightInCm;
public Person(int age, int heightInCm) {
this.age = age;
this.heightInCm = heightInCm;
}
public int getAge() {
return age;
}
public int getHeight() {
return heightInCm;
}
} …
Run Code Online (Sandbox Code Playgroud)