简体   繁体   English

对象列表中元素的相等性检查

[英]Element's equality check from list of object

I have a List of Employee object. 我有一个Employee对象List

class Employee{  
  private int empId;  
  private String name;  
}  

Now I have 我现在有

List<Employee> empList = new ArrayList<Employee>();  

How can I find, if my list contains an employee named "ABC"?? 如果我的列表中包含名为“ ABC”的员工,我如何查找?
empList.contains("ABC"); wont work... 不会工作...

Should I put it in Map ?? 我应该放在Map吗? Which one is more efficient?? 哪个效率更高??

Just wanted to mention that I get my Employee object from database.... 只是想提一下,我从数据库中获取了我的Employee对象。

You can use 您可以使用

Map<String, Employee> map = new HashMap<>();
map.put("ABC", new Employee("ABC"));
map.put("John", new Employee("John"));

and then check 然后检查

map.containsKey("ABC")


Should I put it in Map?? 我应该把它放在地图上吗? Which one is more efficient?? 哪个效率更高??

Because contains() method of list, calls indexOf , which needs to iterate over all elements like this 因为list的contains()方法,所以调用indexOf ,它需要遍历这样的所有元素

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

Where as map no need to iterate over all elements 作为地图,哪里不需要遍历所有元素

Override equals. 覆盖等于。 You can then use List.contains 然后,您可以使用List.contains

class Employee {  
    private empId;  
    private name;
    public boolean equals(Object o) {
        return (o instanceof Employee && ((Employee)o).empId == empId && ((Employee)o).name = name);
    }
}  


List l = ...;
Employee e = new Employee(...);
l.add(e);
l.contains(e);

Since you are storing the Employee objects and not String in your list , i think it is impossible to search without looping through all list objects 由于您将Employee对象而不是String存储在列表中,因此我认为如果不循环遍历所有列表对象就不可能进行搜索

for (Employee employee : empList) {
      if (employee.getName().equals(searchString))
        System.out.println("Found");
    }

Note: Your Employee class should give access to name field either through getter method or change it to public 注意:您的Employee类应该通过getter方法或将其更改为public来访问名称字段


There are other alternatives, but it depends on your requirements and tradeoff's between speed, space, readability, resources etc 还有其他选择,但这取决于您的要求和速度,空间,可读性,资源等之间的权衡

One thing i can think of is HashMap , which has constant time lookup in average case 我能想到的一件事是HashMap ,它在平均情况下具有恒定的时间查找

HashMap<Integer, String> hm = new HashMap<Integer, String>();
hm.put(1, "Tom");
System.out.println(hm.containsValue("Tom"));

Now, 现在,

Should I put it in Map?? 我应该把它放在地图上吗? Which one is more efficient?? 哪个效率更高??

Instead of coding and analyzing, Know Thy Complexities beforehand ! 无需编码和分析,而是提前了解您的复杂性

在Java 8中,如果要确定员工列表中是否包含名为“ ABC”的员工,则可以执行以下操作:

boolean containsABC = empList.stream().anyMatch(emp -> emp.getName().equals("ABC"));

Here is the code that you can use. 这是您可以使用的代码。 I am considering that you want list to return true when empId and name of the Employee matches. 我正在考虑让empIdEmployee name匹配时列表返回true。
I also prefer to use Constructor in your code(Just recommendation). 我也更喜欢在您的代码中使用Constructor(仅推荐)。
The below code will run as you are wanting it to be. 下面的代码将按您希望的那样运行。

class Employee {

    private int empId;
    private String name;

    // below overriden function will return true if it found Employee with 
    // same ID and name
    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Employee             //Checking instace of obj
            && ((Employee)obj).empId == empId       //Checking empId
            && ((Employee)obj).name.equals(name));  //Checking name
    }

    // Used constructor to create Employee
    Employee(int id, String nm) {
        empId = id;
        name = nm;
    }

}


Here is an example run : 这是一个示例运行:

List l = new ArrayList();
l.add(new Employee(1, "ME");
System.out.println(l.contains(new Employee(1, "ME")));  //print true

I would also like to acknowledge you that you should also override hashCode() when you decides to override equals(...) method according to Design Pattern . 我还要感谢您,当您决定根据Design Pattern重写equals(...)方法时,也应该重写hashCode()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM