示例程序:
public final class CollectorTest
{
private CollectorTest()
{
}
private static <T> BinaryOperator<T> nope()
{
return (t, u) -> { throw new UnsupportedOperationException("nope"); };
}
public static void main(final String... args)
{
final Collector<Integer, ?, List<Integer>> c
= Collector.of(ArrayList::new, List::add, nope());
IntStream.range(0, 10_000_000).boxed().collect(c);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,为了简化这里的问题,没有最终的转换,因此生成的代码非常简单.
现在,IntStream.range()生成一个顺序流.我只是将结果打成Integers然后我的设计Collector将它们收集到一个List<Integer>.很简单.
无论我运行多少次这个示例程序,UnsupportedOperationException从不命中,这意味着我的虚拟组合器永远不会被调用.
我有点期待这个,但后来我已经误解了流,我不得不问这个问题......
可以在Collector当流的组合曾经被称为保证是连续的?
我用这个来获得最新的项目.我怎样才能使这个为null安全并且最后(最旧)的空日期排序.createDt是一个joda LocalDate对象.
Optional<Item> latestItem = items.stream()
.sorted((e1, e2) -> e2.getCreateDt().compareTo(e1.getCreateDt()))
.findFirst();
Run Code Online (Sandbox Code Playgroud) 如果我们使用Java 8 Stream就像list.stream().filter(....).collect(..).....它什么时候关闭这个流?
作为下一个例子,我们关闭流我们是好的做法吗?
Stream<String> stream = list.stream();
String result = stream.limit(10).collect(Collectors.joining(""));
stream.close();
Run Code Online (Sandbox Code Playgroud) 我怎么能写组合的方法Stream的Consumers到一个单一的Consumer使用Consumer.andThen(Consumer)?
我的第一个版本是:
<T> Consumer<T> combine(Stream<Consumer<T>> consumers) {
return consumers
.filter(Objects::nonNull)
.reduce(Consumer::andThen)
.orElse(noOpConsumer());
}
<T> Consumer<T> noOpConsumer() {
return value -> { /* do nothing */ };
}
Run Code Online (Sandbox Code Playgroud)
此版本使用JavaC和Eclipse编译.但它太具体了:Stream不能是a Stream<SpecialConsumer>,如果Consumers不是类型T而是超类型,则不能使用:
Stream<? extends Consumer<? super Foo>> consumers = ... ;
combine(consumers);
Run Code Online (Sandbox Code Playgroud)
这不会合理地编译.改进版将是:
<T> Consumer<T> combine(Stream<? extends Consumer<? super T>> consumers) {
return consumers
.filter(Objects::nonNull)
.reduce(Consumer::andThen)
.orElse(noOpConsumer());
}
Run Code Online (Sandbox Code Playgroud)
但Eclipse和JavaC都没有编译:
Eclipse(4.7.3a):
该类型
Consumer未定义andThen(capture#7-of ? extends Consumer<? super …
我有以下代码:
class C
{
String n;
C(String n)
{
this.n = n;
}
public String getN() { return n; }
@Override
public boolean equals(Object obj)
{
return this.getN().equals(((C)obj).getN());
}
}
List<C> cc = Arrays.asList(new C("ONE"), new C("TWO"), new C("ONE"));
System.out.println(cc.parallelStream().distinct().count());
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么distinct返回3而不是2.
鉴于不鼓励在Java EE容器中生成线程.是否也不鼓励在Java EE中使用可能产生线程的Java 8并行流?
我正在为新手程序员编写一个库,所以我试图保持API尽可能干净.
我的库需要做的一件事就是对大量的int或long进行一些复杂的计算.我的用户需要从中计算这些值所需的大量场景和业务对象,因此我认为最好的方法是使用流来允许用户将业务对象映射到IntStream或者LongStream然后计算收集器内的计算.
但是IntStream和LongStream只有3参数collect方法:
collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
Run Code Online (Sandbox Code Playgroud)
而且没有简单的collect(Collector)方法Stream<T>.
所以不是能够做到的
Collection<T> businessObjs = ...
MyResult result = businessObjs.stream()
.mapToInt( ... )
.collect( new MyComplexComputation(...));
Run Code Online (Sandbox Code Playgroud)
我必须提供像这样的供应商,蓄电池和组合器:
MyResult result = businessObjs.stream()
.mapToInt( ... )
.collect(
()-> new MyComplexComputationBuilder(...),
(builder, v)-> builder.add(v),
(a,b)-> a.merge(b))
.build(); //prev collect returns Builder object
Run Code Online (Sandbox Code Playgroud)
对于我的新手用户来说这太复杂了,而且非常容易出错.
我的工作是创建一个静态方法,它接受IntStream或LongStream作为输入,并为您隐藏收集器的创建和执行
public static MyResult compute(IntStream stream, ...){
return .collect(
()-> new MyComplexComputationBuilder(...),
(builder, v)-> builder.add(v),
(a,b)-> a.merge(b))
.build();
} …Run Code Online (Sandbox Code Playgroud) 考虑以下课程:
public class Order {
private String id;
private List<Order> orders = new ArrayList<>();
@Override
public String toString() {
return this.id;
}
// getters & setters
}
Run Code Online (Sandbox Code Playgroud)
注意:重要的是要注意我无法修改此类,因为我正在从外部API中使用它.
还要考虑以下订单层次结构:
Order o1 = new Order();
o1.setId("1");
Order o11 = new Order();
o11.setId("1.1");
Order o111 = new Order();
o111.setId("1.1.1");
List<Order> o11Children = new ArrayList<>(Arrays.asList(o111));
o11.setOrders(o11Children);
Order o12 = new Order();
o12.setId("1.2");
List<Order> o1Children = new ArrayList<>(Arrays.asList(o11, o12));
o1.setOrders(o1Children);
Order o2 = new Order();
o2.setId("2");
Order o21 = new …Run Code Online (Sandbox Code Playgroud) 在Java中是否有办法将函数应用于a的所有元素Stream而不破坏Stream链?我知道我可以打电话forEach,但那个方法会返回一个void,而不是一个Stream.
我有一堆通用项目。我想打印第一个项目的类名+ toString()所有项目的类名。
如果我有一个Iterable,它将看起来像这样:
Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}
Run Code Online (Sandbox Code Playgroud)
我可以Stream<T>使用流API 在流()上执行此操作吗?
*请注意,这是关于流的问题,而不是关于迭代器的问题。我有一个流-没有迭代器。