Как узнать, какой элемент соответствует java-8 anymatch? - PullRequest
0 голосов
/ 08 января 2019

Если у меня есть перечисление

enum Country {
    China, 
    USA, 
    Others
}

Скажи, что у меня есть list1 = ["China", "Shanghai", "Beijing"] и чек для isChina, если true, затем вернуть Country.China.

list2 = ["USA", "Dallas", "Seattle"] и метод проверяет isUSA, если true, то возвращает Country.USA.

Если в списке отсутствуют США или Китай, верните Страна.Другие.

Предположение: список всегда будет содержать только 1 страну, за которой следуют города в этой стране.

[Edit] Не предполагайте, страна будет первым элементом в массиве.

Хотя я нахожу, что это очень легко реализовать в 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 голосов
/ 08 января 2019

Если это предположение верно:

Список всегда будет содержать только 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;
0 голосов
/ 08 января 2019

Как вы сказали, за страной всегда следуют города в указанной стране, что означает, что первым элементом должна быть страна. Исходя из этого, мы можем определить простой вспомогательный метод внутри enum, и все готово:

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.

0 голосов
/ 08 января 2019

Более простое решение с использованием троичных операторов будет:

Country searchCountry(List<String> list) {
    return list.contains("China") ? Country.China : 
            list.contains("USA") ? Country.USA : Country.Others;
}
0 голосов
/ 08 января 2019
Country findCountry(List<String> countries) {
  return Arrays.stream(Country.values())
    .filter(country -> countries.contains(country.name()))
    .findAny()
    .orElse(Country.Others);
}
0 голосов
/ 08 января 2019

Если строка соответствует токену перечисления, то это довольно просто:

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

Предполагается, что первым элементом списка является указанное вами имя.

0 голосов
/ 08 января 2019

Используйте операцию 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);

В качестве альтернативы:

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

Первое решение всегда проверяет «Китай» перед проверкой «США», что является точным эквивалентом вашего императивного подхода. Однако последнее не всегда соблюдает этот порядок, скорее это зависит от порядка перечисления объявления констант в Country.

...