import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.stream.IntStream;
public class Pairs {
public static void main(String[] args) {
List<Double> list = Arrays.asList(-100.0, -90.0, -2.0, 0.0, 3.0, 50.0);
// List<Double> list = Arrays.asList(-100.0, -90.0, -2.0, 0.0, 3.0, 50.0);
// List<Double> list = Arrays.asList(-100.0, -90.0);
// List<Double> list = Arrays.asList(3.0, 50.0);
BiConsumer<Double, Double> action = (value, refValue) -> System.out.println(value+", "+refValue);
{
System.out.println("readability: good, performance 2xO(n) for array list, 2xO(n^2) for linked list");
IntStream
.range(0, list.size())
.filter(idx -> list.get(idx) < 0)
.forEach(idx -> action.accept(list.get(idx), getIf(list, idx+1)));
IntStream
.range(0, list.size())
.filter(idx -> list.get(idx) > 0)
.forEach(idx -> action.accept(list.get(idx), getIf(list, idx-1)));
}
{
System.out.println("readability: fair, performance O(n) for array list, O(n^2) for linked list");
IntStream
.range(0, list.size())
.filter(idx -> list.get(idx) != 0)
.forEach(idx -> { double v = list.get(idx); action.accept(v, getIf(list, idx + (v < 0 ? 1 : -1)));});
}
{
System.out.println("readability: bad, performance O(n) for all lists");
AtomicReference<Double> prev = new AtomicReference<>();
list.stream().forEach(n -> {
Double p = prev.getAndSet(n);
if (n > 0) action.accept(n, p);
else if (p != null && p < 0) action.accept(p, n);
});
if (prev.get() != null && prev.get() < 0) action.accept(prev.get(), null);
}
}
private static Double getIf(List<Double> list, int index) {
return (index < 0 || index >= list.size()) ? null : list.get(index);
}
}