将此标记用于特定于Java 11的问题,Java 11是Java平台的第11版,于2018年9月25日发布。在大多数情况下,您还应指定java标记。
我最近从 Java 8 和 10.0.0.Final 升级到了 Java 11 和 Widfly 15.0.0.Final。但由于某种原因,测试脚本失败并出现以下异常。我已经升级了焊接并且...
使用 Java 流从带有 Set 值的 Map 中查找公共元素集
假设我有一个 HashMap,其中包含作为字符串的键和作为整数集的值(Map>)。 并假设地图填充有以下值: 地图 假设我有一个 HashMap,其中包含作为 String 的键和作为 Set (Integer) 的 Map<String, Set<Integer>> 的值。 并假设地图填充有以下值: Map<String, Set<Integer>> map = new HashMap<>(); map.put("w1", Set.of(1,3,4,6,7)); map.put("w2", Set.of(2,3,4,5,7)); map.put("w3", Set.of(1,2,3,5,7)); 如何使用 Java 中的 Streams 找到所有键的通用值集?例如:在这种情况下,所有键的公共值集是 Set.of(3,7)。 首先请注意,使用流并不总是最干净的方式。 我的想法是获取第一组并迭代其余组以检查它们是否全部包含它: Set<Integer> res = map.values().iterator().next().stream() .filter(item -> map.values().stream().allMatch(set -> set.contains(item))) .collect(Collectors.toSet()); 这是一个简洁的解决方案,但它会检查第一组两次。您还可以添加检查以查看地图是否包含任何条目。 我的方法是首先将不同的值分组并进行计数。然后只保留那些计数等于映射中条目数的条目。这是可行的,因为每个集合只能包含该值一次。 map.values().stream().flatMap(Set::stream) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream().filter(e -> e.getValue() == map.size()) .map(Map.Entry::getKey).collect(Collectors.toSet()); 这可以通过利用 collect() 操作来完成。 此方法背后的逻辑是从值集合中获取随机集,用一个新集包装它以避免突变,然后使用retainlAll()方法将所有集组合在一起一个。 即使值由不可变集表示(如问题中的示例),这也不是问题,因为它们将被完整保留。唯一会发生突变的集合是由collect()内的supplier函数提供的新集合。 如果地图空,可能会出现问题。 在这种情况下,任何从values集合中获取first set的尝试都会失败。因此,这种情况必须单独处理,如下面的方法getFirst()所示。 它可能看起来像: public static Set<Integer> getIntersectionStream(Map<String, Set<Integer>> map) { return map.values().stream() .collect(() -> getFirst(map), Set::retainAll, Set::addAll); } 相同的逻辑可以迭代实现: public static Set<Integer> getIntersectionLoop(Map<String, Set<Integer>> map) { Set<Integer> intersection = new HashSet<>(getFirst(map)); for (Set<Integer> next: map.values()) { intersection.retainAll(next); } return intersection; } 方法 get getFirst() 负责从 values 集合中检索 random set。在空映射的情况下,它将返回一个空的不可修改的集合,否则,它将产生流返回的第一个集合。 注意,在这种情况下,在可选项上调用 get() 是安全的,因为我们期望结果出现。 public static Set<Integer> getFirst(Map<String, Set<Integer>> map) { return map.isEmpty() ? Collections.emptySet() : new HashSet<>(map.values().stream().findFirst().get()); } 主要 public static void main(String[] args) { Map<String, Set<Integer>> map = Map.of("w1", Set.of(1,3,4,6,7), "w2", Set.of(2,3,4,5,7), "w3", Set.of(1,2,3,5,7)); System.out.println(getIntersectionStream(map)); System.out.println(getIntersectionLoop(map)); } 输出 [3, 7] [3, 7] Set<Integer> commonValues(Map<String, Set<Integer>> map) { if (map.isEmpty()) { return new HashSet<>(); } Set<Integer> intersection = new HashSet<>(map.values().iterator().next()); map.values().forEach(v -> intersection.retainAll(v)); return intersection; } 通用且可能有效的解决方案可能是: public static <T> Set<T> retain(Map<?, Set<T>> map) { Iterator<Set<T>> it = map.values().iterator(); if (!it.hasNext()) { return new HashSet<>(); } Set<T> result = new HashSet<>(it.next()); while (it.hasNext() && !result.isEmpty()) { result.retainAll(it.next()); } return result; } 注意 !result.isEmpty(),这是提前退出条件。 IE。如果结果为空,则这些集合没有共同元素。 注意:这是受到MikeFHay的answer的启发。 如果你确实想使用流,并且可以保证Set是可变的,那么你也可以使用reduce()终端操作: public static <T> Set<T> retain(Map<?, Set<T>> map) { return map.values().stream() .reduce((a, b) -> { a.retainAll(b); return a; }) .orElse(Set.of()); } 但请注意,这会修改并返回地图中的第一个集合。 这个简单的版本使用带有集合操作的流来通过查找其中一个成员来填充 intersections,并 retainAll 来匹配所有其他成员: Set<Integer> intersection = new HashSet<>(); map.values().stream().limit(1).forEach(intersection::addAll); map.values().stream().forEach(intersection::retainAll); 我首先建议不要使用流,只需如下所示简单地执行即可。这确实删除了地图的一个元素。 你可以只做 map.get("w1") 并做一个多余的 retainAll。 请注意,由于您使用 Map.of 创建了一个不可变集,我必须制作一个副本以允许修改 result。 Set<Integer> result = new HashSet<>(map.remove("w1")); for (Set<Integer> set : map.values()) { result.retainAll(set); } 这是一个流解决方案。 为了避免使用初始化程序进行归约操作,我将使用 reducing Collector。该收集器返回一个 Optional,因此必须使用 orElse 来检索集合并允许空地图。 Set<Integer> result = map.values().stream() .collect(Collectors.reducing((a, b) -> { a.retainAll(b); return a; }))..orElse(new HashSet<>()); System.out.println(result); 以上都会打印 [3, 7] 显示的解决方案假定已正确填充 Map。 完整的解决方案将包括检查 在我看来,这是最好的解决方案: map.values().stream().reduce((s1, s2) -> { Set<Integer> s3 = new HashSet<>(s2); s3.retainAll(s1); return s3; }).orElse(new HashSet<>()); 它是通过集合相交而减少的地图值流。 这可以使用Stream.reduce来解决: Set<Integer> commonElements = map.values().stream() .reduce((s1, s2) -> s1.stream() .filter(s2::contains) .collect(Collectors.toUnmodifiableSet())) .orElseThrow(NoSuchElementException::new); 归约的每一步都会创建一个新的Set,其中仅包含两个集合之间的共同元素。 我在这里没有做的一个简单的优化(为了简单起见)是有条件地交换 s1 和 s2 ,以便较小的集合被流式传输,因为这是基于大小的线性时间发生的套装中的。
在 Java 中使用流从值为集合的 Map 中查找公共元素集
假设我有一个 HashMap,其中包含作为字符串的键和作为整数集的值(Map)。 并假设地图填充有以下值: 地图 假设我有一个 HashMap,其中包含作为字符串的键和作为整数集的值(Map)。 并假设地图填充有以下值: Map<String, Set<Integer>> map = new HashMap<>(); map.put("w1", Set.of(1,3,4,6,7)); map.put("w2", Set.of(2,3,4,5,7)); map.put("w3", Set.of(1,2,3,5,7)); 如何使用 Java 中的 Streams 找到所有键的通用值集?例如:在这种情况下,所有键的公共值集是 Set.of(3,7) 首先请注意,使用流并不总是最干净的方式。 我的想法是获取第一组并迭代其余组以检查它们是否全部包含它: Set<Integer> res = map.values().iterator().next().stream() .filter(item -> map.values().stream().allMatch(set -> set.contains(item))) .collect(Collectors.toSet()); 这是一个简洁的解决方案,但它会检查第一组两次。您还可以添加检查以查看地图是否包含任何条目。 Set<Integer> commonValues(Map<String, Set<Integer>> map) { if (map.isEmpty()) { return new HashSet<>(); } Set<Integer> intersection = new HashSet<>(map.values().iterator().next()); map.values().forEach(v -> intersection.retainAll(v)); return intersection; } 我的方法是首先将不同的值分组并进行计数。然后只保留那些计数等于映射中条目数的条目。这是可行的,因为每个集合只能包含该值一次。 map.values().stream().flatMap(Set::stream) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream().filter(e -> e.getValue() == map.size()) .map(Map.Entry::getKey).collect(Collectors.toSet()); 这可以通过利用 collect() 操作来完成。 此方法背后的逻辑是从值集合中获取随机集,用一个新集包装它以避免突变,然后使用retainlAll()方法将所有集组合在一起一个。 即使值由不可变集表示(如问题中的示例),这也不是问题,因为它们将被完整保留。唯一会发生突变的集合是由collect()内的supplier函数提供的新集合。 如果地图空,可能会出现问题。 在这种情况下,任何从values集合中获取first set的尝试都会失败。因此,这种情况必须单独处理,如下面的方法getFirst()所示。 它可能看起来像: public static Set<Integer> getIntersectionStream(Map<String, Set<Integer>> map) { return map.values().stream() .collect(() -> getFirst(map), Set::retainAll, Set::addAll); } 相同的逻辑可以迭代实现: public static Set<Integer> getIntersectionLoop(Map<String, Set<Integer>> map) { Set<Integer> intersection = new HashSet<>(getFirst(map)); for (Set<Integer> next: map.values()) { intersection.retainAll(next); } return intersection; } 方法 get getFirst() 负责从 values 集合中检索 random set。在空映射的情况下,它将返回一个空的不可修改的集合,否则,它将产生流返回的第一个集合。 注意,在这种情况下,在可选项上调用 get() 是安全的,因为我们期望结果出现。 public static Set<Integer> getFirst(Map<String, Set<Integer>> map) { return map.isEmpty() ? Collections.emptySet() : new HashSet<>(map.values().stream().findFirst().get()); } 主要 public static void main(String[] args) { Map<String, Set<Integer>> map = Map.of("w1", Set.of(1,3,4,6,7), "w2", Set.of(2,3,4,5,7), "w3", Set.of(1,2,3,5,7)); System.out.println(getIntersectionStream(map)); System.out.println(getIntersectionLoop(map)); } 输出 [3, 7] [3, 7] 通用且可能有效的解决方案可能是: public static <T> Set<T> retain(Map<?, Set<T>> map) { Iterator<Set<T>> it = map.values().iterator(); if (!it.hasNext()) { return new HashSet<>(); } Set<T> result = new HashSet<>(it.next()); while (it.hasNext() && !result.isEmpty()) { result.retainAll(it.next()); } return result; } 注意 !result.isEmpty(),这是提前退出条件。 IE。如果结果为空,则这些集合没有共同元素。 注意:这是受到MikeFHay的answer的启发。 如果你确实想使用流,并且可以保证Set是可变的,那么你也可以使用reduce()终端操作: public static <T> Set<T> retain(Map<?, Set<T>> map) { return map.values().stream() .reduce((a, b) -> { a.retainAll(b); return a; }) .orElse(Set.of()); } 但请注意,这会修改并返回地图中的第一个集合。 这个简单的版本使用带有集合操作的流来通过查找其中一个成员来填充 intersections,并 retainAll 来匹配所有其他成员: Set<Integer> intersection = new HashSet<>(); map.values().stream().limit(1).forEach(intersection::addAll); map.values().stream().forEach(intersection::retainAll); 我首先建议不要使用流,只需如下所示简单地执行即可。这确实删除了地图的一个元素。 你可以只做 map.get("w1") 并做一个多余的 retainAll。 请注意,由于您使用 Map.of 创建了一个不可变集,我必须制作一个副本以允许修改 result。 Set<Integer> result = new HashSet<>(map.remove("w1")); for (Set<Integer> set : map.values()) { result.retainAll(set); } 这是一个流解决方案。 为了避免使用初始化程序进行归约操作,我将使用 reducing Collector。该收集器返回一个 Optional,因此必须使用 orElse 来检索集合并允许空地图。 Set<Integer> result = map.values().stream() .collect(Collectors.reducing((a, b) -> { a.retainAll(b); return a; }))..orElse(new HashSet<>()); System.out.println(result); 以上都会打印 [3, 7] 显示的解决方案假定已正确填充 Map。 完整的解决方案将包括检查 在我看来,这是最好的解决方案: map.values().stream().reduce((s1, s2) -> { Set<Integer> s3 = new HashSet<>(s2); s3.retainAll(s1); return s3; }).orElse(new HashSet<>()); 它是通过集合相交而减少的地图值流。 这可以使用Stream.reduce来解决: Set<Integer> commonElements = map.values().stream() .reduce((s1, s2) -> s1.stream() .filter(s2::contains) .collect(Collectors.toUnmodifiableSet())) .orElseThrow(NoSuchElementException::new); 归约的每一步都会创建一个新的Set,其中仅包含两个集合之间的共同元素。 我在这里没有做的一个简单的优化(为了简单起见)是有条件地交换 s1 和 s2 ,以便较小的集合被流式传输,因为这是基于大小的线性时间发生的套装中的。
假设我们有一个 3 维对象列表。 类自定义{ 整数ID; 列表列表; Custom(id, list) { /* 构造函数 */ } // Getter 和 Setter } 类自定义容器{ ...
我试图理解为什么当我在下面的代码片段中从 y.addAll(x) 更改为 x.addAll(y) 时会出现不同: List 结果 = List.of(1, 2) .parallelStream() .收集...
我正在将以下 yaml 用于 Azure 管道,但出现错误。 即使该映像已安装 Java 11。 知道我做错了什么吗? 错误: ##[错误]Java 11 未预安装...
我试图理解为什么当我在下面的代码片段中从 y.addAll(x) 更改为 x.addAll(y) 时会出现不同: List 结果 = List.of(1, 2) .parallelStream() .收集...
假设我们有一个 3 维对象列表: 类 OneDObject { 整数ID; 列表列表; OneDObject(int id, Listlist) { /* 构造函数 */ } // Getters 和 Sette...
假设我有两个相似的列表(但不相同)。 例如:给定一个整数列表和另一个十六进制字符串列表(可以映射到整数),我如何找到是否有任何共同点
关于 jasperreports 与 Java 11 的兼容性
我正在使用 Java 8 版本 6.10.0 开发 jasperreports 我需要将 Java 8 升级到 Java 11,但是在执行此操作时,我的 jasperreports 既没有下载也没有显示任何错误。 我想要
为 Java 8 编译的依赖于 JAXB 的应用程序 - 可以在 JDK 11 上按原样运行吗?
我正在使用 JAXB 2.3 从 .xsd 文件生成 Java 代码。 我的应用程序当前已编译为 Java 8,但我需要在 OpenJDK 11 上运行它。 我的理解是,将其编译为 Java 11 需要......
Keycloak java.lang.NoClassDefFoundError:使用 Springboot 的 java/security/acl/Group
因此,我们正在构建一个与 Keycloak 集成的 Springboot 后端。但是在 docker swarm 服务上运行后端时出现以下错误: 2020-06-29 21:17:51.694 错误 1 --- [nio-3304...
使用 JDK 11+ 运行 Java FX + Spring 启动应用程序时出现问题
我一直在尝试将用 Java 8 编写的现有 JavaFX 应用程序升级到 Java 17。我对 Java 模块化系统还是新手。 抛出异常 2023-02-23 16:48:59.487 信息 1536 --- [JavaFX-
作为windows服务运行的嵌入式tomcat需要很长时间才能停止服务
我有一个使用嵌入式tomcat(9.0.44)的可执行jar文件。它使用 apache prunsrv 实用程序作为 Windows 服务(名为“MyApp Test Service”)运行。 但当我试图阻止
如何通过添加外部 jar 来解析 SE-11 的 javax.xml.bind?
我有一个足够简单的程序: 导入 javax.xml.bind.JAXBContext; 导入 javax.xml.bind.JAXBException; 公共类主要{ public static void main(String[] args) 抛出 JAXBException {
Pure Spring Security 用户身份验证不起作用
我有一个非常简单的纯 Spring Web 应用程序,带有登录页面(并且它不应该使用 SpringBoot)。我想对用户进行身份验证,然后用户可以继续进行适当的操作
假设LTS版本发布后很多时间。 如果支持期尚未到期,该 LTS 版本是否可以收到更新,尽管即使是较新的 LTS 版本也已经...
Eclipse jdk 11问题:无法解析类型java.lang.String。它是从所需的.class文件间接引用的
我有一个玩具程序,当我尝试使用 Chronicle 导入并编译到语言级别 11 时,该程序仅在 Eclipse 中出现编译错误。该程序在 maven 以及 IntelliJ 中编译和运行(
Tomcat - Java11 - 无法在 SSL 握手期间作为客户端提供 ECDSA 证书
最近,我们的组织将其中一个 Java 应用程序代码从 Java 8 迁移到 Java 11。现在,我们的应用程序面临一个独特的问题。 我们的 tomcat 服务器遇到了奇怪的问题...
在 Swagger CodeGen 中,如何指定带小数位的字段最大值?
我们使用 Java 11 和以下版本的 Swagger Codegen io.swagger.codegen.v3 swagger-codegen-