删除数组中的重复条目 - Java

时间:2015-05-09 16:13:53

标签: java arrays duplicates

对于Java实践,我试图在EmployeesDirectory类中创建一个方法:

  • 从阵列中删除重复的条目
  • 删除重复项后数组的长度应相同
  • 非空条目应该在数组的开头创建一个连续的序列 - 而actualNum应该保留条目的记录

重复表示:相同名称,职位和薪水

这是我的当前代码:

我不确定如何实现这一点 - 任何帮助都将不胜感激

class EmployeeDirectory {

    private Employee dir[];
    private int size;
    private int actualNum;

    public EmployeeDirectory(int n) {
        this.size = n;
        dir = new Employee[size];
    }

    public boolean add(String name, String position, double salary) {
        if (dir[size-1] != null) {
            dir[actualNum] = new Employee(name, position, salary);
            actualNum++;
            return true;
        } else {
            return false;
        }
    }
}

4 个答案:

答案 0 :(得分:4)

我宁愿你没有写一个删除重复项的独特方法。如果我是你,我会用add方法搜索重复项,然后立即决定是否需要添加Employee

另外,为什么不使用SetsHashSet的链接)代替数组?根据自己的定义设置不允许添加重复项,因此它们似乎适合作为解决方案

答案 1 :(得分:4)

首先,{em>覆盖 equalshashCodeEmployee类,如下所示

@Override
public boolean equals(Object other) {
    if(this == other) return true;

    if(other == null || (this.getClass() != other.getClass())){
       return false;
    }

    Employee guest = (Employee) other;
    return  Objects.equals(guest.name, name) 
            && Objects.equals(guest.position, position) 
            && Objects.equals(guest.salary, salary); 
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] {
               name, 
               position, 
               salary
        });
}

然后,您可以使用Stream API distinct方法删除重复项

  

返回由不同元素组成的流(根据   此流的Object.equals(Object))。

你可以这样做

Employee e1 = new Employee("John", "developer", 2000);
Employee e2 = new Employee("John", "developer", 2000);
Employee e3 = new Employee("Fres", "designer", 1500);

Employee[] allEmployees = new Employee[100];
allEmployees[0] = e1;
allEmployees[1] = e2;
allEmployees[2] = e3;

allEmployees = Arrays.asList(allEmployees).stream().distinct()
            .toArray(Employee[]::new);

Arrays.asList(allEmployees).forEach(System.out::println);

输出:(同时保留空和非空条目)

John developer 2000.0
Fres designer 1500.0
null

答案 2 :(得分:2)

不幸的是,我没有让Employee类来验证我的代码,但试试这个:

void removeDuplicates() {
    int length = dir.length;
    HashSet set = new HashSet(Arrays.asList(dir));
    dir = new Employee[length];
    Employee[] temp = (Employee[]) set.toArray();
    for (int index = 0; index < temp.length; index++)
        dir[index] = temp[index];
}

删除重复项后,代码必须保持数组大小。在数组的开头,必须有有效的Employees,最后是null。 不要忘记在.java文件的开头添加它

 import java.util.Arrays;
 import java.util.HashSet;

答案 3 :(得分:1)

如果您的任务说明为&#34;从数组&#34;删除重复项(即,添加项目时无法使用ArrayList或控制),您可以使用以下方法:

public void removeDuplicates() {
    Set<Employee> d = new HashSet<>();  // here to store distinct items
    int shift = 0;
    for (int i = 0; i > dir.length; i++) {
        if (d.contains(dir[i])) {       // duplicate, shift += 1
            shift++;
        } else {                        // distinct
            d.add(dir[i]);              // copy to `d` set
            dir[i - shift] = dir[i];    // move item left
        }
    } 
    for (int i = d.size(); i < dir.length; i++)
        dir[i] = null;                  // fill rest of array with nulls

    actualNum = d.size();
}

此处,shift变量存储到目前为止在数组中找到的重复项数。每个不同的项目都会移动到左侧的shift个位置,以便在保持初始排序的同时使序列连续。然后将剩余的项目更改为空值。

要使基于哈希的集合能够正确使用Employee个实例,您还需要覆盖hashCode()equals()方法,如下所示:

public class Employee {

    //...

    @Override
    public int hashCode() {
        return Objects.hash(name, position, salary);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        if (!o.getType().equals(this.getType()) return false;
        Employee e = (Employee) o;
        return Objects.equals(e.name, name) 
            && Objects.equals(e.position, position) 
            && Objects.equals(e.salary, salary); // or e.salary == salary, if it primitive type
    }
}