Stream.dropWhile () не возвращает правильное значение в двух разных значениях - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь изучить новые возможности Java-9. Я узнал о методе dropWhile в Stream, но он возвращает разные значения в двух разных сценариях.Вот мой код

package src.module;

import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.List;

public class Test {

    public static void main(String[] args) {

        String s[] = new String[3];
        s[0] = "Hello";
        s[1] = "";
        s[2] = "World";
        List<String> value = Stream.of(s).dropWhile(a -> a.isEmpty()).collect(Collectors.toList());

        System.out.println(value);

        List<String> values = Stream.of("a", "b", "c", "", "e", "f").dropWhile(d -> !d.isEmpty())
                .collect(Collectors.toList());
        System.out.println(values);

    }
}

Вот ответ, который я получаю

[Hello, , World]
[, e, f]

Что я думаю, что в первом состоянии должно быть напечатано [, World].Заранее спасибо.

Ответы [ 4 ]

0 голосов
/ 02 октября 2018

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

List<String> value = Stream.of(s).dropWhile(String::isEmpty).collect(Collectors.toList());

на классическую петлю for:

List<String> value = new ArrayList<>();
boolean dropping = true;

for (int i = 0; i < s.length; i++) {
    String str = s[i];
    if (dropping) {
        if (str.isEmpty()) {
            continue;
        }
        dropping = false;
    }
    value.add(str);
}
0 голосов
/ 02 октября 2018

Метод dropWhile , введенный в Java 9, удалит самый длинный начальный набор элементов, которые соответствуют предикату.

Возвращает, если этот поток упорядочен,поток, состоящий из оставшихся элементов этого потока после удаления самого длинного префикса элементов, соответствующих данному предикату.

Поскольку ваше условие состоит в том, что элемент пуст, а первый элемент не пуст,ничего не удаляется, оставляя ["Hello", "", "World"] нетронутым.

В конце, когда вы вызываете dropWhile с противоположным условием, не пусто, первые 3 элемента совпадают и удаляются, оставляя ["", "e", "f"], чтоостальные пункты.

Это ожидаемое поведение.

0 голосов
/ 02 октября 2018

Ваше первое условие - отбрасывать предметы, пока не найден непустой элемент. Второе условие - отбрасывать предметы, пока не будет найден пустой предмет.Добавить '!'к вашему первому условию, чтобы получить прогнозируемый результат.

0 голосов
/ 02 октября 2018

Javadoc dropWhile сообщает:

Возвращает, если этот поток упорядочен, поток, состоящий из оставшихся элементов этого потока после удаления самого длинного префикса элементов, которыйсоответствует данному предикату.

В первом фрагменте первый элемент Stream не удовлетворяет a -> a.isEmpty(), поэтому элементы не удаляются.

Во второмфрагмент, первые 3 элемента в Stream удовлетворяют d -> !d.isEmpty(), поэтому эти 3 элемента отбрасываются, оставляя "", "e" & "f".

...