Потоки - это не путь к go. Это довольно общее утверждение.
Особая проблема здесь в том, что вы не можете сгибать и замыкать .
потоковый решение , которое я придумал, было похоже на @vbezhenar, за исключением того, что оно хорошо себя ведет (имеет объединитель) и не вводит класс аккумулятора.
// Accumulator is: { leftElement, match, rightElement }
// (Could introduce a record.)
// States of the accumulator are:
// { null null null } - initial
// { x null x } - first element
// { x m null } - found match m
// { x null y } - no matches found
Integer[] result = numberList.stream().<Integer[]>collect(
// supplier
() -> new Integer[3],
// accumulator
(acc,t) -> {
if (acc[0] == null) {
// First into acc.
acc[0] = acc[2] = t;
} else if (acc[1] != null) {
// Already found pair to the left.
} else if (t.equals(acc[2])) {
// Found first pair.
acc[1] = t;
acc[2] = null;
} else {
// Otherwise, t replaces rightmost.
acc[2] = t;
}
},
// combiner
(acc, other) -> {
if (acc[1] != null) {
// Alread found pair to the left.
} else if (acc[2] == null) {
// Necessary anyone? Empty acc is combined.
acc[0] = other[0];
acc[1] = other[1];
acc[2] = other[2];
} else if (acc[2].equals(other[0])) {
// Found match.
acc[1] = acc[2];
acc[2] = null;
} else {
// Otherwise, leftmost element with rest as other acc.
acc[1] = other[1];
acc[2] = other[2];
}
}
);
return result[1] != null;
На самом деле я не проверял объединитель , Я подозреваю, что большинство объединителей никогда не тестировались .
Если мы сделаем такие же предположения о поведении потока, как @vbezhenar, то dropWhile
- наш друг Джонни 5.
return numberList.stream().dropWhile(new Predicate<>() {
Integer last;
public boolean test(Integer t) {
Integer lastLast = last;
last = t;
return !t.equals(lastLast);
}
}).findFirst().isPresent();
Анонимные внутренние классы ftw !!