gpt4 book ai didi

java - 在 Iterable 上查找元素

转载 作者:行者123 更新时间:2023-12-02 06:10:57 25 4
gpt4 key购买 nike

我有以下类(class):

public static class GenerateMetaAlert implements WindowFunction<Tuple2<String, Boolean>, Tuple2<String, Boolean>, Tuple, TimeWindow> {
@Override
public void apply(Tuple key, TimeWindow timeWindow, Iterable<Tuple2<String, Boolean>> iterable, Collector<Tuple2<String, Boolean>> collector) throws Exception {
//code
}
}

我想要做的是,对于集合中的每个元素,在字段中都存在具有相反值的任何其他元素。

<小时/>

一个例子:

Iterable: [<val1,val2>,<val3,val4>,<val5,val6>,...,<valx,valy>]
|| || || ||
elem1 elem2 elem3 elemn

我想测试什么:

foreach(element)
if elem(i).f0 = elem(i+1).f0 then ...
if elem(i).f0 = elem(i+2).f0 then ...
<...>
if elem(i+1).f0 = elem(i+2).f0 then ...
<...>
if elem(n-1).f0 = elem(n).f0 then ...

我认为使用这样的东西是可能的:

  Tuple2<String, Boolean> tupla = iterable.iterator().next();
iterable.iterator().forEachRemaining((e)->{
if ((e.f0 == tupla.f0) && (e.f1 != tupla.f1)) collector.collect(e);});

但是就像我是 Java 新手一样,我不知道如何以最佳方式做到这一点。

<小时/>

这是使用 Apache Flink 的 Java 程序的一部分:

.keyBy(0, 1)
.timeWindow(Time.seconds(60))
.apply(new GenerateMetaAlert())
<小时/>

Testing:

使用以下代码:

public static class GenerateMetaAlert implements WindowFunction<Tuple2<String, Boolean>, Tuple2<String, Boolean>, Tuple, TimeWindow> {
@Override
public void apply(Tuple key, TimeWindow timeWindow, Iterable<Tuple2<String, Boolean>> iterable, Collector<Tuple2<String, Boolean>> collector) throws Exception {
System.out.println("key: " +key);
StreamSupport.stream(iterable.spliterator(), false)
.collect(Collectors.groupingBy(t -> t.f0)) // yields a Map<String, List<Tuple2<String, Boolean>>>
.values() // yields a Collection<List<Tuple2<String, Boolean>>>
.stream()
.forEach(l -> {
System.out.println("l.size: " +l.size());
// l is the list of tuples for some common f0
while (l.size() > 1) {
Tuple2<String, Boolean> t0 = l.get(0);
System.out.println("t0: " +t0);
l = l.subList(1, l.size());
l.stream()
.filter(t -> t.f1 != t0.f1)
.forEach(t -> System.out.println("t: "+ t));
}
});
}
}

结果是:

key: (868789022645948,true)
key: (868789022645948,false)
l.size: 2
l.size: 2
t0: (868789022645948,true)
t0: (868789022645948,false)

此测试的结论:就像条件 .filter(t -> t.f1 != t0.f1) 从未满足

如果我将 .filter(t -> t.f1 != t0.f1) 更改为 .filter(t -> t.f1 != true) (或 false)过滤器有效

我还使用以下内容:

    final Boolean[] aux = new Boolean[1];
<...>
Tuple2<String, Boolean> t0 = l.get(0);
aux[0] = t0.f1;
<...>
.filter(t -> !t.f1.equals(aux[0]))

但即使如此,我也没有任何输出(只有当我使用t.f1.equals(aux[0])

时才有输出)

最佳答案

Iterable 允许您根据需要在其元素上获取任意数量的 Iterator,但每个迭代器都会迭代所有 元素,而且只有一次。因此,您使用 forEachRemaining() 的想法将不会如您所愿。由于您要生成一个新的 Iterator 来调用该方法,因此它将从开头开始,而不是在另一个迭代器最近提供的元素之后开始。

您可以做的是使用 IterableSpliterator 创建一个 Stream,并使用分组依据 Collector 按可迭代元组的第一个值对元组进行分组。然后您可以根据需要处理元组列表。

例如,虽然我对这是否是您真正想要的有些怀疑,但这实现了问题中描述的逻辑:

StreamSupport.stream(iterable.spliterator(), false)
.collect(Collectors.groupingBy(t -> t.f0)) // yields a Map<String, List<Tuple2<String, Boolean>>>
.values() // yields a Collection<List<Tuple2<String, Boolean>>>
.stream()
.forEach(l -> {
// l is the list of tuples for some common f0
while (l.size() > 1) {
Tuple2<String, Boolean> t0 = l.get(0);
l = l.subList(1, l.size());
l.stream()
.filter(t -> t.f1 != t0.f1)
.forEach(t -> collect(t));
}
});

请注意,这可以多次收集相同的元组,如下伪代码所示。如果您想要不同的东西,例如仅收集表示给定 f0f1 值翻转的元组,每个元组一次,那么您可能需要 lambda 的不同实现外部 forEach() 操作。

关于java - 在 Iterable 上查找元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55906725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com