Java 8减少到2个字符串

Ido*_*ash 4 java java-8 java-stream

我可以用溪流做这个吗?

StringBuilder text = new StringBuilder();
StringBuilder dupText = new StringBuilder();
String lastLetter = "";

for (Container cont : containersList) {
    String letter = cont.getLetter();
    text.append(letter);
    if (letter.equals(lastLetter) == false) {
        dupText.append(letter);
    }
    lastLetter = letter;
}

System.out.println(text);
System.out.println(dupText);
Run Code Online (Sandbox Code Playgroud)

我查看一下continers列表,每个都有一个char.我需要组装两个字符串 - 一个是所有字符组合,另一个是所有字符但没有耦合重复(ABABAAAB - > ABABAB)

这可以用流完成吗?

我尝试这样做:

Optional<String> text = containersList.stream()
            .map(Container::getLetter)
            .reduce((letter,accumalator) -> accumalator += letter);

Optional<String> dupText = session.containersList().stream()
            .map(Container::getLetter)
            .reduce((letter, accumalator) ->{
                if ((accumalator.endsWith(letter) == false)) {
                    accumalator += letter;
                }
                return accumalator;
            });
Run Code Online (Sandbox Code Playgroud)

Tun*_*aki 5

使用StreamEx

您可以使用StreamEx库在单个Stream管道中执行此操作.

List<Container> containersList = Arrays.asList(new Container("A"), new Container("B"), new Container("A"), new Container("A"), new Container("B"));

String[] result =
        StreamEx.of(containersList)
                .map(Container::getLetter)
                .groupRuns(Object::equals)
                .collect(MoreCollectors.pairing(
                    MoreCollectors.flatMapping(List::stream, Collectors.joining()),
                    MoreCollectors.mapping(l -> l.get(0), Collectors.joining()),
                    (s1, s2) -> new String[] { s1, s2 }
                ));

System.out.println(result[0]);
System.out.println(result[1]);
Run Code Online (Sandbox Code Playgroud)

此代码创建容器的Stream,并将每个容器映射到其字母.

然后,该方法groupRuns折叠成List与给定谓词匹配的连续元素.在这种情况下,谓词是字符串的相等:所以如果你从流开始[A, A, B],这个方法会将它折叠成Stream [List(A, A), List(B)](第一个元素是A输入中2个连续元素的列表).

最后,这是收集pairing器收集,允许收集到两个不同的收集器.第一个连接每个列表的平面映射结果,而第二个连接仅列表的第一个元素(因此删除连续的元素).

结果存储在一个数组中,该数组仅用作两个值的持有者.

输出:

ABAAB
ABAB
Run Code Online (Sandbox Code Playgroud)

直接使用Stream API

如果您想继续使用当前的API并且不使用库,那么您最好的选择是编写自定义Collector:

public static void main(String[] args) {
    List<Container> containersList = Arrays.asList(new Container("A"), new Container("B"), new Container("A"), new Container("A"), new Container("B"));

    String[] result = containersList.stream().parallel().map(Container::getLetter).collect(ContainerCollector.collector());

    System.out.println(result[0]);
    System.out.println(result[1]);
}

private static final class ContainerCollector {

    private StringBuilder text = new StringBuilder();
    private StringBuilder dupText = new StringBuilder();

    private void accept(String letter) {
        text.append(letter);
        if (dupText.indexOf(letter, dupText.length() - letter.length()) < 0) {
            dupText.append(letter);
        }
    }

    private ContainerCollector combine(ContainerCollector other) {
        text.append(other.text);
        other.dupText.codePoints().forEach(i -> {
            String letter = new String(Character.toChars(i));
            if (dupText.indexOf(letter, dupText.length() - letter.length()) < 0) {
                dupText.append(letter);
            }
        });
        return this;
    }

    private String[] finish() {
        return new String[] { text.toString(), dupText.toString() };
    }

    private static Collector<String, ?, String[]> collector() {
        return Collector.of(ContainerCollector::new, ContainerCollector::accept, ContainerCollector::combine, ContainerCollector::finish);
    }

}
Run Code Online (Sandbox Code Playgroud)

这种风俗收藏家构建textdupText每个字母被接受时.对于textString,始终附加字母.对于dupText,仅当最后一个字母不同时才附加该字母.

组合器代码(在并行执行的情况下运行)对于以下内容来说有点棘手dupText:如果第二个没有从第一个结束开始,则附加第二个.否则,将删除第一个字母,并附加其余字母.

输出是一样的.