我有两个清单
List<Foo> foolist = getAll();
List<Bar> barList = getAll();
class Foo {
String name;
String age;
....
// more fields
}
class Bar {
String barName;
int codeBar;
....
// more field
}
我们可以用 age<->codeBar 和 name<->barName 来建立它们之间的关系我想得到不傻的 Bar 对象,如何使用流来完成?
我看到使用 stream().filter(list::contains) 的示例,但在这种情况下无效。
谁能指出我正确的方向?
谢谢大家。我看起来像这样:barList.stream().filter(b->fooList.stream().anyMatch(f->!b.getBarName().equalsIgnoreCase(f.getName) && b.getCodeBar() == Integer.valueOf(age))).collect(Collectors.toList());
还不知道对不对
你可以这样做:
public static void main(String[] args) {
List<Foo> fooList = asList(new Foo("1", "1"), new Foo("2", "2"), new Foo("3", "3"));
List<Bar> barList = asList(new Bar("4", 4), new Bar("3", 3), new Bar("5", 5));
Set<Blah> fooSet = fooList.stream().map(Main::fooToBlah).collect(toCollection(HashSet::new));
Set<Blah> barSet = barList.stream().map(Main::barToBlah).collect(toCollection(HashSet::new));
barList.stream()
.filter(bar -> !fooSet.contains(barToBlah(bar)))
.forEach(System.out::println);
fooList.stream()
.filter(foo -> !barSet.contains(fooToBlah(foo)))
.forEach(System.out::println);
}
static Blah fooToBlah(Foo foo) {
return new Blah(foo.name, foo.age);
}
static Blah barToBlah(Bar bar) {
return new Blah(bar.barName, "" + bar.codeBar);
}
static class Blah {
String name;
String age;
public Blah(String name, String age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
}
Foo
对象并将它们转换为Blah
(当然适当命名) - 这是必需的,因为Foo
还有我们不关心的其他字段。Blah
对象放入 a 中,HashSet
这样您就不会以O(n*m)
时间复杂度告终。你可以只做collect(toSet())
,但我更愿意在这里明确说明它,因为它对性能很重要。Bar
对象,如果一个对象不在上面的集合中,那就是不常见的Bar
对象。它需要转换为Blah
,不幸的是您不能使用,Stream.map
因为最终它应该仍然是Stream<Bar>
,而不是Stream<Blah>
。Foo
对象。请记住,课堂上需要equals
和hashCode
方法Blah
。Foo
和Bar
类不需要他们。
编辑:
您可以转换以下代码
Set<Blah> fooSet = fooList.stream().map(Main::fooToBlah).collect(toCollection(HashSet::new));
barList.stream()
.filter(bar -> !fooSet.contains(barToBlah(bar)))
.forEach(System.out::println);
变成这样
barList.stream()
.filter(bar -> fooList.stream()
.map(Main::fooToBlah)
.noneMatch(foo -> foo.equals(barToBlah(bar)))
)
.forEach(System.out::println);
甚至Blah
完全删除类
barList.stream()
.filter(bar -> fooList.stream().noneMatch(foo -> Objects.equals(foo.name, bar.barName) && Objects.equals(foo.age, "" + bar.codeBar)
.forEach(System.out::println);
但是你最终会得到更糟糕的时间复杂度,然后还有一个可读性问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句