如何知道java-8中的哪个元素匹配anymatch?

Jav*_*per 6 java java-8 java-stream

假设我有一个枚举

enum Country {
    China, 
    USA, 
    Others
}
Run Code Online (Sandbox Code Playgroud)

假设我有一个 list1 = ["China", "Shanghai", "Beijing"]检查isChina,如果是,则返回Country.China.

list2 = ["USA", "Dallas", "Seattle"]并且方法检查isUSA,如果为true则返回Country.USA.

如果列表中缺少美国或中国,则返回Country.Others.

假设:列表将始终只包含一个国家/地区,后面跟着该国家/地区的城市.

[编辑]不要假设,country将是数组中的第一个元素.

虽然我发现在Java-7中实现起来非常容易,但我不确定使用流来实现这一目标的最优雅方式

for (String str: list) {
   if (str.equals("China")) {
       return Country.China  
   } 
   if (str.equals("USA")) {
       return Country.USA; 
   }
}
return Country.Other;
Run Code Online (Sandbox Code Playgroud)

我正在寻找使用Streams的干净实现.

Ous*_* D. 6

filter对条件使用操作并findFirst获得第一个匹配,然后转换为相应的Country.China,Country.USA否则返回(Country.Others如果不匹配).

 return list.stream()
            .filter(str -> "China".equals(str) || "USA".equals(str))
            .findFirst()
            .map(s -> "China".equals(s) ? Country.China : Country.USA)
            .orElse(Country.Others);
Run Code Online (Sandbox Code Playgroud)

或者:

return Stream.of(Country.values()) // or Arrays.stream(Country.values())
             .filter(o -> list.contains(o.toString()))
             .findFirst().orElse(Country.Others);
Run Code Online (Sandbox Code Playgroud)

在检查"USA"之前,第一个解决方案将始终检查"China",这与您的命令式方法完全等效.但是,后者并不总是尊重该顺序,而是取决于枚举常量声明的顺序.Country.

  • @Andreas根据_illustrated_代码,它表现为`findFirst`,而不是`findAny` (3认同)
  • 好吧,说明代码是一个循环,并且不可能编写一个循环来证明作者不关心顺序(就像顺序流上的`anyMatch`在大多数情况下仍然返回第一个匹配).所以@Andreas关于OP引用"anyMatch"的评论是正确的.你的第一个变体中的谓词首先检查"中国"的事实是完全无关紧要的,因为字符串无论如何都无法匹配.交换订单不会改变结果.你也可以写`.filter(str - > str.matches("China | USA"))`或`.filter(Set.of("China","USA"):: contains)`. (2认同)