我正在努力学习如何更好地使用流,我认为使用流可能会有更好的代码。
List<Integer> origList = Arrays.asList(1,2,3,4,5,6);
List<Integer> newList = new ArrayList<>();
//Need at least a first and a last
if(origList.size < 2) {
return newList;
}
//Add First
newList.add(origList.get(0));
//Play leap frog and only add ever other item in the middle
for(int i = 1; i < origList.size() - 1; i++) {
if(i%2 == 1) {
newList.add(origList.get(i));
}
}
//Add Last
newList.add(origList.get(origList.size-1));
System.out.println(newList); // expect: [1,2,4,6]
答案 0 :(得分:1)
我会留在循环中。但是,不是迭代所有数字,只是通过模数测试跳过每一秒,首先迭代每个第二个数字:
newList.add(origList.get(0));
int last = origList.size() - 1;
for(int i = 1; i < last; i += 2) newList.add(origList.get(i));
newList.add(origList.get(last));
您可以使用流
List<Integer> newList = IntStream.concat(IntStream.of(0),
IntStream.concat(IntStream.range(0, last / 2).map(i -> i * 2 + 1), IntStream.of(last)))
.mapToObj(origList::get)
.collect(Collectors.toList());
但它不一定是对循环版本的改进......
答案 1 :(得分:0)
好的,您可以使用自定义收集器来完成此操作。但收藏家并不是很好。无论如何,你走了:
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
public class MyCollector<T> implements Collector<T, MyCollector.DataHolder<T>, List<T>> {
static class DataHolder<T> {
T first;
T last;
List<T> evens = new LinkedList<>();
List<T> odds = new LinkedList<>();
boolean hasFirst = false;
boolean hasLast = false;
boolean even = true;
void accummulate(T next) {
if (!hasFirst) {
hasFirst = true;
first = next;
return;
}
if (!hasLast) {
hasLast = true;
last = next;
return;
}
T cur = last;
last = next;
if (even) {
evens.add(cur);
} else {
odds.add(cur);
}
even = !even;
}
DataHolder<T> combine(DataHolder<T> other) {
if (!hasFirst)
return other;
if (hasLast) {
if (even) {
evens.add(last);
odds.add(other.first);
evens.addAll(other.evens);
odds.addAll(other.odds);
last = other.last;
even = other.even;
} else {
odds.add(last);
evens.add(other.first);
odds.addAll(other.evens);
evens.addAll(other.odds);
last = other.last;
even = !other.even;
}
} else {
if (even) {
evens.add(other.first);
odds.addAll(other.evens);
evens.addAll(other.odds);
last = other.last;
even = !other.even;
} else {
odds.add(other.first);
evens.addAll(other.evens);
odds.addAll(other.odds);
last = other.last;
even = other.even;
}
}
return this;
}
List<T> finish() {
if (hasFirst)
evens.add(0, first);
if (hasLast)
evens.add(last);
return evens;
}
}
@Override
public Supplier<DataHolder<T>> supplier() {
return DataHolder::new;
}
@Override
public BiConsumer<DataHolder<T>, T> accumulator() {
return DataHolder::accummulate;
}
@Override
public BinaryOperator<DataHolder<T>> combiner() {
return DataHolder::combine;
}
@Override
public Function<DataHolder<T>, List<T>> finisher() {
return DataHolder::finish;
}
@Override
public Set<Characteristics> characteristics() {
return Collections.emptySet();
}
// Test main, just to show off.
public static void main(String[] args) {
System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6).stream().collect(new MyCollector<>()));
}
}
答案 2 :(得分:0)
引用有效最终(常量引用)计数器:
AtomicInteger count = new AtomicInteger();
List<Integer> newList = origList.stream()
.filter(x -> count.getAndIncrement() % 2 == 1)
.collect(Collectors.toList());
newList.add(0, origList.get(0));
Optional.of(origList.size()).filter(n -> n % 2 == 1).ifPresent(n -> newList.add(origList.get(n - 1)));
此代码根据样本输入生成所需的输出。