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

时间:2019-01-07 23:33:42

标签: java java-8 java-stream

假设我有一个枚举

enum Country {
    China, 
    USA, 
    Others
}

说我有一个 list1 = ["China", "Shanghai", "Beijing"]并检查isChina,如果为true,则返回Country.China。

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

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

假设:列表始终只包含1个国家/地区,然后是该国家/地区中的城市。

[编辑]不要以为国家是数组中的第一个元素。

虽然我发现在Java-7中实现起来非常容易,但我不确定使用流执行此操作的最佳方式

for (String str: list) {
   if (str.equals("China")) {
       return Country.China  
   } 
   if (str.equals("USA")) {
       return Country.USA; 
   }
}
return Country.Other;

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

6 个答案:

答案 0 :(得分:6)

对条件使用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);

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

答案 1 :(得分:3)

如果字符串与枚举令牌匹配,则非常简单:

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

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

答案 2 :(得分:3)

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

Country searchCountry(List<String> list) {
    return list.contains("China") ? Country.China : 
            list.contains("USA") ? Country.USA : Country.Others;
}

答案 3 :(得分:1)

Country findCountry(List<String> countries) {
  return Arrays.stream(Country.values())
    .filter(country -> countries.contains(country.name()))
    .findAny()
    .orElse(Country.Others);
}

答案 4 :(得分:1)

正如您所说,“国家/地区”之后始终是该国家/地区中的城市,这意味着第一个要素必须是国家/地区。由此,我们可以在枚举中定义一个简单的辅助方法,然后完成:

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。

答案 5 :(得分:1)

如果该假设成立:

  

列表将始终仅包含1个国家/地区,然后是该国家/地区中的城市。

然后,比较列表的第一个元素并返回匹配的enum元素就足够了,否则回退到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;