我有一张这样一些价值观的 map :

Map<String, String> roleMap = new HashMap<>();
map.put(1,"A");
map.put(2,"B;C;D");
map.put(3,"A;C");

以及一些限制值的列表:

List<String> restrictedList= List.of("B", "C");

我需要判断值"A"是否出现在 map 的每个键中,而不是与限制列表中的一个值一起出现,然后抛出一些错误.

我成功地做到了这一点,但我认为完全使用streams而不是半途而废可以做得更好.

这是我的解决方案:

map.forEach((key, value) -> {
    if (Arrays.stream(value.toString().split(";"))
        .anyMatch(role -> "A".contains(role))
            && CollectionUtils.containsAny(Arrays.asList(value.toString().split(";")), restrictedList)) {
        errorsList.add(String.format("%s combination can't be used with 'A'", value))
    };
});

上述场景的结果应该输出密钥号3无效,因为只有密钥号3包含"A以及受限列表中的一些值.

但我想知道如何用流实现它?

我在anyMatch()之前试过filter(),但没用.

推荐答案

您可以在 map 的值上创建一个流,并对其应用filter()操作两次:

  • 找出代码中的目标字符串("A")是否包含在映射值中;
  • 以确定特定 map 值与给定限制列表之间是否存在交集.

这两张支票都是anyMatch()美元.

为了提高判断受限列表的性能,它被包装成了HashSet.

通过对每个值执行一次split()操作来创建字符串数组,以减少开销.

目标值("A")、错误消息和分隔符(";")被动态地传递给方法,而不是硬编码.

代码可能如下所示:

public static List<String> getErrorList(List<String> restricted,
                                        Map<String, String> map,
                                        String targetValue, // in your code "A"
                                        String errorMessage,
                                        String delimiter) {
    
    Set<String> restrictedSet = new HashSet<>(restricted); // list is being wrapped by the set to improve performance
    
    return map.values().stream()          // Stream<String>
        .map(str -> str.split(delimiter)) // Stream<String[]>
        .filter(arr -> Arrays.stream(arr).anyMatch(targetValue::equals))     // contain the target value
        .filter(arr -> Arrays.stream(arr).anyMatch(restrictedSet::contains)) // contains any of the restricted values
        .map(arr -> String.join(delimiter, arr))                             // Stream<String>
        .map(str -> String.format("%s %s %s", str, errorMessage, targetValue))
        .collect(Collectors.toList());
}

main()-演示

public static void main(String[] args) {
    Map<String, String> roleMap =
        Map.of("1","A", "2","B;C;D", "3","A;C");
    
    List<String> restrictedValues = List.of("B", "C");
    
    String errorMessage = " combination can't be used with ";
    String targetValue = "A";

    System.out.println(getErrorList(restrictedValues, roleMap, targetValue, errorMessage, ";"));
}

100

[A;C  combination can't be used with  A]

Java相关问答推荐

那么比较似乎不是词典学的,尽管doctor 这么说

虚拟线程似乎在外部服务调用时阻止运营商线程

更新我们的一个文物后出现了严重的符号引用错误

gitlab ci不会运行我的脚本,因为它需要数据库连接'

如何打印本系列的第n项y=-(1)-(1+2)+(1+2+3)+(1+2+3+4)-(1+2+3+4+5)...Java中的(1+2+3+4...+n)

条件加载@ManyToMany JPA

使用Testcontainers与OpenLiberty Server进行集成测试会抛出SocketException

如何从错误通道回复网关,使其不会挂起

如何使用Jackson将XML元素与值和属性一起封装

如何仅使用键/ID的一部分(组合)高效地返回映射值?

虚拟线程应该很快消亡吗?

如何在我的世界中为互动增加冷却时间?

如何配置空手道以使用FeignClient或RestTemplate代替ApacheHttpClient

有谁能帮我修一下这个吗?使输出变得更加整洁

我如何为我的Java抵押贷款代码执行加薪操作(&Q)

为什么我不能建立输入/输出流?Java ServerSocket

用于Java的Visual Studio代码完成不起作用

如何使用Java对随机生成的字母数字优惠券代码进行过期设置

Intellij 2023 IDE:始终在顶部显示菜单栏

java中的网上购物车解析错误