当前位置: 首页 > 知识库问答 >
问题:

是否有一种通用方法来获取Java中两个列表的交集?

高朝明
2023-03-14

有没有一种通用的方法来获取Java中两个列表的交集?

我想有一个方法,可以找到列表1和列表2中包含的元素,无论列表中的元素是字符串、Long、整数还是BigDecimal类型。

我试图通过下面的代码来实现这一点,这些代码可以正常工作,直到两个参数都包含相同类型的元素,否则它在运行时返回一个空列表。

private <T> List<T> intersect(List<T> list1, List<T> list2) {
        
    List<T> list = new ArrayList<T>();
    
    System.out.println("list1= "+list1);
    System.out.println("list2= "+list2);
    for (T t2 : list2) {
        System.out.println("t2= "+t2 + ", class: " + t2.getClass());
    }
    
    for (T t : list1) {
        System.out.println("t= "+t + ", class: " + t.getClass());
        if(list2.contains(t)) {
            System.out.println("list2 containts t");
            list.add(t);
        }
    }
    System.out.println("list= "+list);
    return list;
}

调用intersect方法的代码:

import javax.ws.rs.core.Response;

public boolean process(Response response, List<Object> sentObjects) {
String body = response.readEntity(String.class);
....
List<Object> parsedResponse = parseJson(body);
List<Object> intersection = intersect(sentObjects, parsedResponse);
...
}

列表中包含不同类型元素的示例输出:

list1= [11190, 11191, 11213]
list2= [11190, 11191, 11213]
t2= 11190, class: class java.lang.Long
t2= 11191, class: class java.lang.Long
t2= 11213, class: class java.lang.Long
t= 11190, class: class java.math.BigDecimal
t= 11191, class: class java.math.BigDecimal
t= 11213, class: class java.math.BigDecimal
list= []

问题:是否有任何方法可以强制实现list1的类型T与list2的类型T相同,而无需明确说明确切的类型?

共有3个答案

和嘉澍
2023-03-14

也许你可以直接使用Object类。如果你只是使用Object类的子类。希望有帮助。

宇文温文
2023-03-14

Collection.contains的定义只允许使用相等性检查元素;不同类的实例通常不相等(例如,Long零和BigDecimal零不相等;然而空ArrayList和空LinkedList是)。

为了解决这个问题,您需要使用比equals更通用的东西,例如BiPredicate

if(list2.stream().anyMatch(u -> biPredicate.apply(t, u))) {

您需要将双向谓词作为参数传递给您的方法,例如

BiPredicate<Number, Number> biPredicate = (t, u) -> t.longValue() == u.longValue();

甘永春
2023-03-14

您可以在检查相等性之前选择所有元素都可以转换为的通用类型。Object.equals()方法依赖于实现,但它很少为不同类型的对象返回true,尤其是在参数不是派生类型的情况下。

在这种特殊情况下,常见的类型似乎是字符串。也就是说,长整型、整数型和十进制都可以一致地转换为字符串表示形式。

据推测,您正在使用的String对象是没有分隔符的十进制数字(代表数千个等)。如果是这种情况,您可以简单地在数字类型上调用toString()来创建等效表示。否则,您可以使用适当配置的NumberFormat来匹配String元素的预期格式。

List<T> intersect(List<? extends T> t1, Collection<?> t2) {
    Set<String> tmp = t2.stream().map(Object::toString).collect(Collectors.toSet());
    return t1.stream()
        .filter(e -> tmp.contains(e.toString()))
        .collect(Collectors.toList());
}
 类似资料:
  • 我写了一个代码来检查两个列表之间的交集。我只需要有交集。有没有更快的方法。

  • 问题内容: 目前,我正在研究Java代理以汇编内存统计信息。借助工具API,我可以持有这些类(并对其进行操作)。使用纯Java,我可以估算每个对象使用的资源。到目前为止,一切都很好。 我现在面临的问题是“如何掌握特定类的每个Object实例”。我可以进行字节码操作以获得对象实例的所有权,但是我希望还有另外一个我不知道的API,它可以帮助我完成我的目标而无需进行如此繁琐的干预。最后,应将对性能的影响

  • 我需要写一个私人的方法在java接收2数组。有没有办法使他们必须是相同的长度? 比如: 公共静态无效方法(int[]arr1,int[]arr2[arr1.length])

  • 问题内容: 我正在尝试将长度不定的多个数据列表输出到CSV文件。每个列表应该是输出CSV文件中的一列。有直接的做事方法吗?如果我将每个列表输出为一行,那么我将遍历每个列表并在结束时输出返回值,但是这种方法在按列工作时不起作用。 我曾想过一次逐项检查所有列表并增加一个计数器,但这也会失败,因为有些列表比另一些​​更长。为了解决这个问题,我将不得不在每次迭代时检查计数器是否在每个列表的末尾,这在计算方

  • 我可以检查一个帐户是否是一个广告组的成员,但有没有办法告诉一个帐户是否属于一个OU?我想搜索由你而不是由广告组,我不确定如果这是可能的。下面是我如何搜索一个广告组。

  • 我正在寻找一个更优雅的方法,将这个指令列表变成一个单一的合并指令,其中键'SKU'作为合并的键。这些列表实际上都是很容易被转化为指令的模型。我没有找到一个更优雅的解决方案使用Pydantic。 Dicts/PydanticInstances列表 所需输出: 当前解决方案: