当前位置: 首页 > 面试题库 >

如何以一种很好的方式在Java的同一列表中查找对象对

呼延子安
2023-03-14
问题内容

在里面

我有一个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 是开箱即用的:它使用和方法比较对象。对于简单的对象,