【问题标题】:Comparing 2 ArrayLists and returning the common elements比较 2 个 ArrayList 并返回公共元素
【发布时间】:2021-11-13 23:05:12
【问题描述】:

我正在尝试比较两个 ArrayList(即 ArrayList、list1 和 ArrayList)testQueryValue 并返回它们之间的共同元素。以下是我尝试过的

private List<Loading> matchLists(List<Loading> list1 ,List<Test>  list2) {
        
    List<Loading> matchCriteria = new ArrayList<Loading>(list1);
    List<String>testQueryValue= list2.get(0).getTestQueryValues();
    for(Loading match: list1) {
    for(Sring test: testQueryValue){
        if (matchCriteria.contains(test)) {
            matchCriteria.add(test); // Error: The method add(Loading) in the type List<Loading> is not applicable for the arguments (String)
        }
    }
    return matchCriteria;
}

如上编辑此代码后,得到代码中注释行中的错误。

我知道这个问题已经被问过好几次了。根据答案,我尝试过这种方法并且无法返回匹配项。 我正在遍历 list1 的每个元素,它是一个加载列表,它包含嵌套数组,并检查是否有任何元素包含测试(testQueryValue 的子集)?然后添加 test 作为方法返回的 matchCriteria 的最后一个元素。

提前感谢您的帮助

【问题讨论】:

  • “matchCriteria 正在返回 null。” - 我没有看到任何名为matchCriteria 的东西可以返回任何东西或者可能是null。你的意思是列表是空的? (由于您使用contains(match),它不应该直接包含null)。
  • 另外,MatchCriteriagetList2QueryValues() 等似乎都不是 JDK 类,那么您使用的是什么库?您需要详细说明,添加一些示例输入和所需输出,最好提供minimal reproducible example
  • @Thomas 我已经编辑了代码。这两个列表不是空的,我已经对其进行了调试,并且看到了值。抱歉,我将 MatchCriteria 引用变量进一步用于设置一些 lombok 值。我在编辑中删除了关于提供示例值的内容。我不应该分享,因为这是我的项目数据。
  • 您的方法返回List&lt;String&gt;List&lt;Loading&gt; 中的哪一个?
  • 好吧,你不能调用matchCriteria.add(test);,但需要从test 创建一个Loading 实例(它的工作原理取决于我上面所说的相同的事情)。假设有一个Loading(String) 构造函数和equals()hashCode() 的良好实现,你可以做类似Loading testLoading = new Loading(test); if( !matchCriteria.contains(testLoading) ) { matchCriteria.add(testLoading); } 的事情——或者更好的是,使用SetLinkedHashSet,如果你需要保持秩序),因为这会已经处理重复,所以不需要!contains() 检查。

标签: java arrays arraylist collections


【解决方案1】:

显然,matchCriteria.add(test) 不适用于 List&lt;Loading&gt; matchCriteriaString test

相反,您需要首先使用test 的任何内容创建Loading 的实例。这意味着您需要一个像 Loading(String data) 这样的构造函数,它能够构建一个合理的 Loading 实例。

为了使用matchCriteria.contains(Loading)Loading 类需要有一个合理的equals(Object) 实现,并且通过契约hashCode() 也是如此。

最后,我假设您只想添加一个 Loading 实例,前提是 matchCriteria 中尚不存在该实例,即您不希望重复。这意味着你最好用一套,例如像这样:

//LinkedHashSet keeps insert order
Set<Loading> matchCriteria = new LinkedHashSet<>(list1);

List<String>testQueryValue = list2.get(0).getTestQueryValues();
for(Loading match: list1) {
  for(Sring test: testQueryValue){
      matchCriteria.add(new Loading(test));
  }
}

return new ArrayList<>(matchCriteria);

如果您想继续使用列表,您的内部循环可能需要如下所示:

for(Sring test: testQueryValue){
  Loading testLoading = new Loading(test);
  if( !matchCriteria.contains(testLoading) ) {
    matchCriteria.add();
  }
}

或者,如果您只想在需要时创建 Loading 实例,请使用以下内容:

Map<String, Loading> matches = new LinkedHashMap<>();
list1.forEach(loading -> matches.put(loading.getStringRepresentation, loading) );

for(Sring test: testQueryValue){
  matches.computeIfAbsent(test, key -> new Loading(key));
}

return new ArrayList<>(matches.values());

【讨论】:

    【解决方案2】:

    你可以使用retainAll()方法

    public class Person {
    
        private String name;
        private String surName;
        private int age;
        
        public Person(String name) {
            super();
            this.name = name;
            
        }
        public Person(String name, String surName, int age) {
            super();
            this.name = name;
            this.surName = surName;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", surName=" + surName + ", age=" + age + "]";
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) obj;
            return Objects.equals(name, other.name);
        }
        
        
        
    }
    
    public class PersonTest {
        public static void main(String[] args) {
    
            List<Person> listofPerson = new ArrayList<>();
            listofPerson.add(new Person("Jane", "Brown", 18));
            listofPerson.add(new Person("John", "Smith", 20));
            listofPerson.add(new Person("Adam", "Williams", 18));
            
            List<Person> listofPerson2 = new ArrayList<>();
            listofPerson2.add(new Person("Jane", "Brown", 18));
            listofPerson2.add(new Person("John", "Smith", 20));
            listofPerson2.add(new Person("Adam", "Williams", 18));
            listofPerson2.add(new Person("Bravo", "Joan", 18));
            
            listofPerson2.retainAll(listofPerson);
            System.out.println(listofPerson2);
    
        }
    }
    

    样本输出

    [Person [name=Jane, surName=Brown, age=18], Person [name=John, surName=Smith, age=20], Person [name=Adam, surName=Williams, age=18]]
    

    由于我已经覆盖了参数name 的equals 方法,它将保留lists 中具有相同name 的所有元素。

    在你的情况下,你可以试试下面的方法。

    public static void main(String[] args) {
    
        List<Person> listofPerson = new ArrayList<>();
        listofPerson.add(new Person("Jane", "Brown", 18));
        listofPerson.add(new Person("John", "Smith", 20));
        listofPerson.add(new Person("Adam", "Williams", 18));
    
        List<String> listofPerson2 = new ArrayList<>();
        listofPerson2.add("Jane");
        listofPerson2.add("John");
        listofPerson2.add("Adam");
        listofPerson2.add("Bravo");
        Map<String, Person> personMap = listofPerson.stream()
                .collect(Collectors.toMap(Person::getName, Function.identity()));
        List<Person> finalList = listofPerson2.stream().filter(name -> personMap.containsKey(name))
                .map(name -> personMap.get(name)).collect(Collectors.toList());
        System.out.println(finalList.toString());
    }
    

    【讨论】:

    • 但我正在比较一个人员列表和一个字符串列表。
    • 我已经编辑了我的答案,希望它能解决您的问题。
    • Person1 "Jane", "Brown", 18 "John", "Smith", 20 "Adam", "Williams", 18 Person2 Jane Williams 的列表 我希望输出为: "简", "布朗", 18, matchCriteria="Jane"
    • 对不起,我没有得到你。
    • 这里 finalList 将有匹配的元素,使用你的逻辑来操作输出:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    相关资源
    最近更新 更多