我目前正在开展一个项目,我有以下内容
for (String x : listOne) {
for (String y : listOne) {
for (String z : listTwo) {
if (x.noun1.equal(z.noun1) && y.noun2.equals(z.noun2)) {
doSomething();
}
}
}
}
其中listOne和listTwo只是ArrayList<String>
s。两个ArrayList
都持有动词:名词:名词对,其中我们在索引0处有一个动词,在索引1处有一个名词,在索引2处有一个名词(依此类推)。
这基本上只是一种强力搜索算法。 为了优化搜索过程,我想创建一个较小的三元组列表,它具有与z相同的名词1和一个较小的三元组列表,它们具有相同的名词2 ž。我对Java中的lambda表达式一无所知,但经过一些研究,我确信在java中使用lambdas可以做到这一点。
关于我如何进行此操作的任何帮助,或任何可能有用的文章将不胜感激。
编辑:这是一个例子
ArrayList<String> al1 = "IsA","Car","Vehicle","IsA","house","building"..
ArrayList<String> al2 = "IsA","house","home"..
由于索引4处的al1
名词1等于索引1处的al2
s名词1.我们返回一个包含&#34; IsA&#34;的新ArrayList或Map, &#34;房子&#34;&#34;建筑&#34;
答案 0 :(得分:1)
你应该把你以前的问题联系起来,否则你很难理解你想要的东西。 IIUYC你要求将三色列表转换为三元组列表。这很简单:
@RequiredArgsConstructor
@EqualsAndHashCode
@ToString
public static class Triplet {
public static List<Triplet> listFrom(List<String> strings) {
Preconditions.checkArgument(strings.size() % 3 == 0);
final List<Triplet> result = new ArrayList<>();
for (int i=0; i<strings.size(); i+=3) {
result.add(new Triplet(
strings.get(i), strings.get(i+1), strings.get(i+2)));
}
return result;
}
public final String verb;
public final String noun1;
public final String noun2;
}
以上注释来自project lombok并完全按照他们的说法行事。如果您不想使用Lombok,请手动编写需要的内容。
这实际上是全部,但我会扩展上一个问题。上面没有使用lambdas,现在你得到两个。
您准备数据
final List<Triplet> tripletsOne = Triplet.listFrom(listOne);
final List<Triplet> tripletsTwo = Triplet.listFrom(listTwo);
final Map<String, List<Triplet>> mapOneByNoun1 = tripletsOne.stream()
.collect(Collectors.groupingBy(t -> t.noun1));
final Map<Object, List<Triplet>> mapOneByNoun2 = tripletsOne.stream()
.collect(Collectors.groupingBy(t -> t.noun2));
final List<Triplet> EMPTY = Collections.emptyList();
由于Collectors.groupingBy,这比我之前的方法更简单。
在两种情况下都发生z
,在最外层的循环中使用它是有意义的
for (final Triplet z : tripletsTwo) {
for (final Triplet x : mapOneByNoun1.getOrDefault(z.noun1, EMPTY)) {
for (final Triplet y : mapOneByNoun2.getOrDefault(z.noun2, EMPTY)) {
doSomething(x, y);
}
}
}
就是这样。
答案 1 :(得分:0)
不确定你为什么要找lambda?请提供方案..
如果您的输入是具有快速随机访问权限的列表,则可以使用索引流来解决您的问题:
public static List<String> f(int n, List<String> input) {
int fence = IntStream.range(0, input.size())
.filter(idx -> input.get(idx).equals("B")) // leave only B's
.skip(n-1)
.findFirst() // an index of n-th B
.getAsInt(); // with throw NoSuchElementException if not enough B's
return input.subList(0, fence+1);
}
答案 2 :(得分:0)
我想您想了解如何构建for
循环?
写了一个简单的for
来理解你的预期结果。这是你想要达到的目标吗?
// Considering we have these lists..
// ArrayList<String> al1 = "IsA","Car","Vehicle","IsA","house","building"..
// ArrayList<String> al2 = "IsA","house","home"..
List<String> result = new ArrayList<>();
for(int i=0; i<al1.size(); i+=3) {
for(int j=0; j<al2.size(); j+=3) {
if(i+2 < al1.size() && j+2 < al2.size()) {
if (al1.get(i).equals(al2.get(i)) && al1.get(i+1).equals(al2.get(i+1))) {
result.add(al1.get(i));
result.add(al1.get(i+1));
result.add(al1.get(i+2));
}
}
}
}
对于第二次检查,我:e。要检查名词2,可以更新条件以添加名词2的新检查 -
if (
(al1.get(i).equals(al2.get(i)) && al1.get(i+1).equals(al2.get(i+1))) ||
(al1.get(i).equals(al2.get(i)) && al1.get(i+2).equals(al2.get(i+2)))
) { .. }