【问题标题】:How to compare to Arraylist of object based on key in efficient way如何以有效的方式基于键与对象的 Arraylist 进行比较
【发布时间】:2021-10-15 23:38:47
【问题描述】:

如何以有效的方式与基于 key 的对象的 Arraylist 进行比较。

我有一个对象 personDetails 和 departmentDetails 的数组。

这里我试图根据名为deptCode的属性找出两个对象之间的区别。

这是我正在尝试的。

package com.education;

import java.util.*;
import java.util.stream.Collectors;

public class educationMain {

    public static void main(String[] args) {
        
        List<person> list=new ArrayList<person>();  
        person l1 = new person(1,"Samual",100,"Sales","Business");
        person l2 = new person(2,"Alex",100,"Sales","Business");
        person l3 = new person(3,"Bob",101,"Engineering","Technology");
        person l4 = new person(4,"Michel",101,"Engineering","Technology");
        person l5 = new person(5,"Ryan",102,"PR","Services");
        person l6 = new person(6,"Horward",103,"Leadership","Managmnet");
        person l7 = new person(7,"Cyna",104,"HR","Human Resource");
        list.add(l1);  
        list.add(l2);  
        list.add(l3); 
        list.add(l4);  
        list.add(l5);  
        list.add(l6); 
        list.add(l7); 
        
        
        
         List<department> depList = new ArrayList<department>();
         
         
         department d1 = new department(100, "Sales","Business");
         department d2 = new department(101, "Engineering","Technology");
         department d3 = new department(102, "PR","Services");
         depList.add(d1);  
         depList.add(d2);  
         depList.add(d3); 

         List<person> listC = new ArrayList<person>();
         
         
         for(person p : list) {
             boolean  flag = false;
             for (department d:depList) {
                 if(p.deptCode == d.deptCode) {
                     flag = false;
                     break;
                 }else {
                     flag = true;
                 }
             }
             if(flag == true) {
                 listC.add(p);
             }
         }
         
         for(person b:listC){  
             System.out.println(b.personId+" "+b.name+" "+b.deptCode+" "+b.parentDept+" "+b.deptName); 
         }
    }

}

现在这打印出我想要的东西。但我使用了两个 for 循环。谁能帮我优化我的代码,因为我在这里使用了两个循环。我想尝试根据一些过滤掉增量的代码。

在 Collection 中,我看到 set 可以,但不能写。佳能帮我优化效率。

输出:

6 Horward 103 Leadership Managmnet

 7 Cyna 104 HR Human Resource

【问题讨论】:

  • 您正在寻找list 中的person 对象,其deptCodedepartments 的deptCodes 中的任何 个不匹配?这是这个算法的意图吗?
  • @jason44107 完全一样。我已经更新了我的问题中的输出。一些有效的方法会有所帮助。

标签: java arraylist data-structures collections


【解决方案1】:

给定大小为p 的人员列表和大小为d 的部门列表,您当前的算法的复杂度为O(p * d)

您可以迭代部门一次并将其部门代码添加到HashSet&lt;Integer&gt; 并检查每个人的部门代码集 - 复杂性:O(d + p)。 这在需要更多内存的同时计算效率更高 - 经典的时间与内存权衡:

List<Person> persons = ...;
List<Department> departments = ...

Set<Integer> existingDepartmentIds = new HashSet<>();
for (Department d : departments) {
    existingDepartmentIds.add(d.deptCode); 
}

List<Person> personsWithMatchingDepartmentId = new ArrayList<>();
for (Person p : persons) {
   if (existingDepartmentIds.contains(p.deptCode)) {
       personsWithMatchingDepartmentId.add(p);
   }
}

我不知道你是否精通Stream 等,所以我以命令式风格写了这篇文章。函数变体看起来像这样:

List<Person> persons = ...;
List<Department> departments = ...

Set<Integer> existingDepartmentIds = departments.stream()
   .map(Department::getDeptCode)
   .collect(Collectors.toSet());


List<Person> personsWithMatchingDepartmentId = persons.stream()
    .filter(p -> existingDepartmentIds.contains(p.deptCode))
    .collect(Collectors.toList());

【讨论】:

  • 我正在尝试 acn 你建议任何可行的例子。
【解决方案2】:

roookeee 已经给出了很好的答案。我的方法大致相同,这是我的实现:

将所有部门添加到列表后,遍历部门,将代码添加到 HashSet。我不确定类方法到底是什么,但是,假设它们遵循 JavaBean 约定,它可能看起来像这样:

//Create an instance of HashSet
HashSet<Integer> codeSet = new HashSet<>();

//Iterate over the departments and add the department code to a set.
depList.forEach(dept->{
    codeSet.add(dept.getDeptCode());
  });


List<person> listC = new ArrayList<>();

list.forEach(p->{
    if(!codeSet.contains(p.getDeptCode())){
    listC.add(p);
    }
  });

/**
 *This reads logically as, "For each person, if the set of department codes 
 *DOES NOT contain this persons department code, add them to the list".
 */

请原谅任何糟糕的代码格式,因为我一直在尝试学习 Python,所以我有一段时间没有说 Java。另外,我没有专业的编程经验,我只是一个觉得编码有点整洁的少年,所以,不要把我的话当成福音。

【讨论】:

  • 出于好奇,一个快速的问题..这发生在对象的一个​​属性上。我们可以为多个属性做同样的逻辑吗
  • 当然,如果您想检查多个条件,您只需在 if 语句中添加“and”或“or”即可。即,if(x &amp;&amp; y){\\do something} 的意思是“如果 x 和 y 都为真,则做某事。if(x || y){\\do something} 的意思是“如果 x 或 y 中的一个或两个都为真,则做某事。”
  • 我在这里单独询问过。 stackoverflow.com/questions/68766785/…
  • 在效率方面我不太确定,我必须花一些时间考虑一下。我对时间复杂度的研究还不够,无法让这些事情自然而然地出现在我身上。我会检查一下,也许稍后再回答。
  • 您想检查列表 a 的每个元素与列表 b 的数据有关 - 如果没有两个循环,这是不可能的。该算法可以更改为不使用嵌套循环(如解释),但我们无法摆脱这两个循环
猜你喜欢
  • 1970-01-01
  • 2014-12-07
  • 2023-03-23
  • 2017-02-24
  • 2020-10-17
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多