我有一个ArrayList
不同的对象。我试图在条件的基础上搜索相同的列表对象对。如果我找到正确的对,则我将创建一个新对象并将其添加到新列表中。但是我想避免在objectA与objectB配对以及objectB与objectA配对时创建对象对。
直到现在,我还没有找到一种好的方法。
2 for循环
for(Object objectA : objectList){
for(Object objectB : objectList){
if(condition){
// create new object
// add to list
}
}
}
问题:我需要标记已经匹配的对,否则我将避免为同一对创建两个对象。它有效,但可能不是最佳解决方案吗?
迭代器
像具有两个forloops的版本一样,我使用了迭代器,并从列表中删除了已经匹配的对象对。可行,但似乎不那么好?
Java8 forEach和removeIf
objectList.stream().forEach(posA -> {
objectList.removeIf(posB -> condition);
});
问题:何时创建对象对对象…?
哪个是最好的主意-还是我没有得到更好的解决方案?
显然,您考虑一个无序对,其中pair(a,b)与pair(b,a)相同。为此,您必须自己创建一个类,例如
class Pair<T> {
final T a, b;
public Pair(T a, T b) {
this.a = a;
this.b = b;
}
@Override
public boolean equals(Object obj) {
if(obj==this) return true;
if(!(obj instanceof Pair)) return false;
Pair<?> p=(Pair<?>)obj;
return Objects.equals(this.a, p.a) && Objects.equals(this.b, p.b)
|| Objects.equals(this.a, p.b) && Objects.equals(this.b, p.a);
}
@Override
public int hashCode() {
return Objects.hashCode(a) + Objects.hashCode(b);
}
}
有了一个具有所需语义的类,您可以简单地创建所有组合并让Stream API删除重复项。如果源列表已经重复,这甚至可以工作:
List<YourNewObjectType> result = objectList.stream()
.flatMap(objA -> objectList.stream().map(objB -> new Pair<>(objA,objB)))
.distinct()
.filter(pair -> condition)
.map(pair -> new YourNewObjectType … )
.collect(Collectors.toList());
您未指定是否允许某个元素与其自身配对。如果没有,您可以过滤掉以下情况:
List<YourNewObjectType> result = objectList.stream()
.flatMap(objA -> objectList.stream()
.filter(objB -> !Objects.equals(objA, objB))
.map(objB -> new Pair<>(objA,objB)))
.distinct()
.filter(pair -> condition)
.map(pair -> new YourNewObjectType … )
.collect(Collectors.toList());
附带说明一下,如果结果类型的构造没有副作用且不昂贵,并且该类型具有反映两个输入元素的相等性,则可以考虑构造它们而不是Pair
实例并.distinct
用于它们,从而节省了转换Pair
实例到YourNewObjectType
实例。
如果您的源列表中没有重复项,则可以利用这些知识基于索引构建唯一对:
List<YourNewObjectType> result = IntStream.range(0, objectList.size())
.mapToObj(i -> IntStream.range(i/*+1*/, objectList.size())
.mapToObj(j -> new Pair<>(objectList.get(i),objectList.get(j))))
.flatMap(Function.identity())
.filter(pair -> condition)
.map(pair -> new YourNewObjectType … */)
.collect(Collectors.toList());
如果不允许将元素与自身配对,只需将/*+ 1*/
注释变为real即可+1
。该代码可读性较差,但可能更有效。
问题内容: 我正在寻找Java的良好排序列表。到处搜寻可以给我一些有关使用TreeSet / TreeMap的提示。但是这些组件缺少一件事:随机访问集合中的元素。例如,我想访问排序集中的第n个元素,但是使用TreeSet时,我必须遍历其他n-1个元素,然后才能到达那里。因为我的集合中最多有数千个元素,所以这很浪费。 基本上,我正在寻找与.NET中的排序列表类似的东西,能够快速添加元素,快速删除元素
问题内容: 我有一个从控制器传递到JSP的Player对象的列表,我想以几种不同的方式在同一页面上显示它们: 按名称排序的菜单 按赢/输百分比排序的列表 我可以在模型中放置单独的排序后的副本,但是处理显示相同列表的不同方法似乎更像是视图的责任,因此,我希望避免将逻辑放入控制器中。我已经有几个实现Comparator的类来帮助实际排序。 在JSP中执行此操作的最佳方法是什么? 我可以在将列表传递到其
问题内容: 我需要对列表中的最后一个元素执行一些特殊的操作。有没有比这更好的方法了? 问题答案: 如果您不想复制列表,可以制作一个简单的生成器: notlast的另一种定义:
假设我有一个名为House的对象,它包含一个列表 对于房间,只有一个属性,其值由int表示: 现在,使用Java8,并给出一个带有
我是java新手,正在努力克服它。我有类似(< code>String URL,int Score)的数据,我想在数组列表中实现它。我研究了如何在< code>ArrayList或< code>LinkedList中实现多种类型的变量,发现解决方案是从超类创建子类,我创建了这个子类: 我的超级班是: 当我尝试使用添加对象时,我遇到了错误?该错误说: 类型ArrayList中的add(int,MyS
问题内容: 我有一个可能具有或不具有相同属性值的对象的列表/集合。获得具有相同属性的对象的不同列表的最简单方法是什么?一种收集类型最适合此目的吗?例如,在C#中,我可以使用LINQ执行以下操作。 我最初的想法是使用lambdaj(链接文本),但似乎不支持此功能。 问题答案: 使用接口的实现(类T可能需要自定义方法,您可能必须自己实现)。通常,a 是开箱即用的:它使用和方法比较对象。对于简单的对象,