Как вернуть весь список, если фильтр ложен - PullRequest
0 голосов
/ 31 января 2019

У меня есть этот список

List<String> lstStr = new ArrayList<>();
lstStr.add("1");
lstStr.add("2");
lstStr.add("3");
lstStr.add("4");
lstStr.add("5");

Когда я ищу строку "1" , она должна вернуть List<String> = ["1"], и если строка поиска отсутствует в списке, например "0" должно вернуть все List <String> =["1","2","3","4","5"].Это может быть достигнуто с помощью потока Java?Пожалуйста, покажите пример.

Я пробовал это, используя код ниже, но я мог получить весь список, когда я ищу, скажем "0"

List<String> filteredLst = lstStr.stream()
                                  .filter(data-> "1".equalsIgnoreCase(data))
                                  .collect(Collectors.toList());

filteredLst.forEach(data2 -> System.out.println(data2));

Спасибозаранее.

Ответы [ 5 ]

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

Для этой цели вы можете использовать собственный коллектор.

li.stream().filter(d->"0".equalsIgnoreCase(d)).collect(
            Collector.of(
                    ArrayList::new,
                    ArrayList::add,
                    (a, b) -> {
                        a.addAll(b);
                        return a;
                    },
                    a -> a.isEmpty() ? li : a
            )
    );

Ищите документы по коллектору: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

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

Если вам не нужно обрабатывать дубликаты, вы можете сделать следующее:

static List<String> getOneOrAll(List<String> list, String element) {
    return list.stream()
               .filter(element::equalsIgnoreCase)
               .findFirst()
               .map(Collections::singletonList)
               .orElse(list);
}

...
List<String> result = getOneOrAll(lstStr, "1");

В противном случае вы можете передать предикат и отфильтровать дубликаты:

static <T> List<T> getOneOrAll(List<T> list, Predicate<T> predicate) {
    List<T> filteredList = list.stream()
                               .filter(predicate)
                               .collect(toList());
    return filteredList.isEmpty() ? list : filteredList;
}

...
List<String> result = getOneOrAll(lstStr, "1"::equals);
// or
List<String> resultIgnoringCase = getOneOrAll(lstStr, "1"::equalsIgnoreCase);
0 голосов
/ 31 января 2019

Сначала проверьте, содержит ли ваш список это значение.Если да, тогда перейдите к фильтрации списка или просто распечатайте предыдущий список

if(!lstStr.contains("0")) {
        lstStr.forEach(data2 -> System.out.println(data2));
    }else {
    List<String> filteredLst = lstStr.stream()
            .filter(data-> "1".equalsIgnoreCase(data))
            .collect(Collectors.toList());
    filteredLst.forEach(data2 -> System.out.println(data2));
    }
0 голосов
/ 31 января 2019

Возможная простая утилита для этого будет использовать contains:

List<String> findAndReturnValue(List<String> lstStr, String value) {
    return lstStr.contains(value) ? Arrays.asList(value) : lstStr;
}

и для возможных дубликатов в списке:

List<String> findAndReturnValue(List<String> lstStr, String value) {
    return lstStr.contains(value) ?
            lstStr.stream()
                    .filter(a -> a.equalsIgnoreCase(value)) // condition as in question
                    .collect(Collectors.toList()) : lstStr;
}

Чтобы уменьшить сложность для случаев, когдаэлемент будет присутствовать в списке, более простое решение - собрать список и затем проверить его размер:

List<String> findAndReturn(List<String> lstStr, String value) {
    List<String> filteredLst = lstStr.stream()
            .filter(data -> data.equalsIgnoreCase(value))
            .collect(Collectors.toList());
    return filteredLst.isEmpty() ? lstStr : filteredLst;
}
0 голосов
/ 31 января 2019

Вы можете разделить предикат и вернуть непустой список:

Map<Boolean, List<String>> split = lstStr.stream()
        .collect(Collectors.partitioningBy("1"::equalsIgnoreCase));

List<String> filteredLst = split.get(Boolean.TRUE).isEmpty() ? 
                        split.get(Boolean.FALSE) : //can also use lstStr instead
                        split.get(Boolean.TRUE);

Collectors.partitioningBy("1"::equals) вернет карту с 2 записями, где true будет ключом записей, которые соответствуют вашемуфильтр, а false ключ от остальных.

filteredLst должен содержать значение, сопоставленное с true, если оно не пустое, или значение false в противном случае (что, несомненно, будет таким же, как в исходном списке)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...