小编Rob*_*ain的帖子

Java 8 Collectors.toMap SortedMap

我正在使用Java 8 lambdas并希望Collectors toMap用来返回一个SortedMap.我能想出的最好的是调用下面Collectors toMap用假设法mergeFunctionmapSupplier等于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)

java lambda java-8 java-stream collectors

64
推荐指数
5
解决办法
3万
查看次数

Collectors.toSet()和HashSet

采取以下示例代码行:

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 java-8 java-stream collectors

63
推荐指数
1
解决办法
3万
查看次数

Java 17 的 parallelStream() 会导致在 Java 16 中正常运行的代码出现严重的性能问题。为什么?

我正在开发一款在 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-oraclelinux8openjdk: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) …

java jetty java-stream java-17

34
推荐指数
1
解决办法
4149
查看次数

Java 8 lambdas组列表进入映射

我想借此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最好地实现这一目标?

java java-8 java-stream

33
推荐指数
2
解决办法
2万
查看次数

当从实例方法返回一个没有引用其封闭类的匿名类时,它会引用它.为什么?

当从实例方法返回没有引用其封闭类的匿名类时,它会引用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)

java anonymous-class

14
推荐指数
1
解决办法
1226
查看次数

此代码使用ecj但不使用javac编译.这是ecj,javac或两者中的错误吗?

以下代码创建一个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)

java javac ecj

12
推荐指数
1
解决办法
173
查看次数

java.lang.ExceptionInInitializerError 与 Java-16 | jlClassFormatError 可访问:模块 java.base 不会“打开 java.lang”到未命名的模块

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)

java cglib java-16

8
推荐指数
1
解决办法
3904
查看次数

Java 8 lambdas按多个字段分组

我有一个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和值是ListPojo的对象表示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>>>我的愿望?

更新

提供的第一个答案对于最初提供的示例是正确的,但是我已经更新了问题.鲁本在接受的答案中的评论提供了最后一块拼图.

java java-8 java-stream collectors

6
推荐指数
1
解决办法
8690
查看次数

在java.util.function.Function中声明

假设我有class哪些implements java.util.function.Function.在Function需要了解的开始日期和结束日期,但这些将是整个函数的生存期内保持不变.

我正在考虑为开始日期和结束日期实现Functionwith private final字段,因为该apply方法不需要为每个调用使用新值.我觉得这将简化我的实现,但担心这违背了整个函数式编程范例.

Functionapply方法需要值但在整个生命周期内保持不变的情况下,使用不可变类成员是否合理 Function

lambda java-8 java-stream

6
推荐指数
1
解决办法
548
查看次数

Java 8 lambdas多个过滤器调用

filter(Predicate<? super T> predicate)在Java 8 lambda表达式中使用调用时,我有两种想法,即是否将所有Predicate逻辑放在一个调用中,或者链接filter(Predicate<? super T> predicate)调用以在适当的时候提供可读性.

我认为链接filter(Predicate<? super T> predicate)调用会很便宜,因为他们还没有遇到终结符,所以在可读性方面会犯错,但我对StreamsAPI的了解不够充分,无法完全理解权衡取舍的内容.

借助以下示例(考虑更复杂的谓词),哪种实现更优越:List<Person> usingOneFilterList<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)

java lambda java-8 java-stream

6
推荐指数
1
解决办法
7854
查看次数