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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何知道java-8中的哪个元素匹配anymatch?相关的知识,希望对你有一定的参考价值。

假设我有一个枚举

enum Country {
    China, 
    USA, 
    Others
}

假设我有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;

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

答案

使用filter操作条件和findFirst获得第一个匹配,然后转换为相应的Country.ChinaCountry.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);

或者:

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

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

另一答案

如果字符串与枚举标记匹配,那么它非常简单:

return Arrays.stream(Country.values())
    .filter(c -> c.name().equals(list.get(0))
    .findAny().orElse(Country.Others);

这假设列表的第一个元素是您指定的名称。

另一答案

使用三元运算符的更简单的解决方案是:

Country searchCountry(List<String> list) {
    return list.contains("China") ? Country.China : 
            list.contains("USA") ? Country.USA : Country.Others;
}
另一答案
Country findCountry(List<String> countries) {
  return Arrays.stream(Country.values())
    .filter(country -> countries.contains(country.name()))
    .findAny()
    .orElse(Country.Others);
}
另一答案

正如你所说,国家总是跟着这个国家的城市,这意味着第一个元素必须是国家。从那里我们可以在枚举中定义一个简单的帮助方法,我们已经完成了:

public static Country valueOf(String value){
    for(Country country : values()){
        if(country.name().equals(value)){
            return country;
        }
    }
    return Country.Others;
}

然后你可以用以下方法调用该方法:

Country country = Country.valueOf(list1.get(0));

无需使用Java8。

另一答案

如果这个假设成立:

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

然后,比较列表的第一个元素并返回匹配的枚举元素就足够了,否则回退到Country.Others

因此,根据问题陈述,不需要迭代列表,因此根本不需要使用流。

您的Java 7代码也不是最好的,因为它会迭代列表。如果你想要一个单行,三元运算符会这样做:

return "China".equals(list.get(0)) ? Country.China :
       "USA".equals(list.get(0))   ? Country.USA   :
                                     Contry.Others;

我甚至会考虑list.get(0)

String first = list.get(0);
return "China".equals(first) ? Country.China :
       "USA".equals(first)   ? Country.USA   :
                               Contry.Others;

以上是关于如何知道java-8中的哪个元素匹配anymatch?的主要内容,如果未能解决你的问题,请参考以下文章

当多个路径匹配时,Express 如何知道使用哪个路由器路径?

浏览器如何知道哪个元素应该获得点击或悬停事件?

如何知道点击了哪个元素

具有任何匹配属性的对象的 JAVA 8 过滤器列表

确定一个列表是不是由 Java 8 中的字谜元素组成

java JAVA 8中的朴素字符串模式匹配实现