一个替代方案是,您可以实现Collector接口。
public static void main(String[] args)
{
Collector<Integer, List<Integer>, List<Integer>> sieve = new Collector<Integer, List<Integer>, List<Integer>>()
{
@Override
public Supplier<List<Integer>> supplier()
{
return ArrayList::new;
}
@Override
public BiConsumer<List<Integer>, Integer> accumulator()
{
return (prevPrimes, candidate) ->
{
if (prevPrimes.stream().noneMatch(p -> candidate % p == 0))
{
prevPrimes.add(candidate);
}
};
}
@Override
public BinaryOperator<List<Integer>> combiner()
{
return (list1, list2) ->
{
list1.addAll(list2);
return list1;
};
}
@Override
public Function<List<Integer>, List<Integer>> finisher()
{
return Function.identity();
}
@Override
public Set<Characteristics> characteristics()
{
Set<Characteristics> set = new HashSet<>();
set.add(Characteristics.IDENTITY_FINISH);
return set;
}
};
List<Integer> primesBelow1000 = IntStream.range(2, 1000)
.boxed()
.collect(sieve);
primesBelow1000.forEach(System.out::println);
}
更简洁地说:
public static void main(String[] args)
{
List<Integer> primesBelow1000 = IntStream.range(2, 1000)
.boxed()
.collect(
ArrayList::new,
(primes, candidate) ->
{
if (primes.stream().noneMatch(p -> candidate % p == 0))
{
primes.add(candidate);
}
},
List::addAll
);
primesBelow1000.forEach(System.out::println);
}
更高效(使用Java 9的TakeWhile将O(n)改为O(sqrt(n))):
List<Long> primesBelowLimit = LongStream.range(2, below)
.collect(
ArrayList::new,
(primes, candidate) ->
{
long candidateRoot = (long) Math.sqrt(candidate);
if (primes.stream()
.takeWhile(p -> p <= candidateRoot)
.noneMatch(p -> candidate
{
primes.add(candidate);
}
},
List::addAll
);