Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
删除Array-Java中的重复项_Java_Arrays_Duplicates - Fatal编程技术网

删除Array-Java中的重复项

删除Array-Java中的重复项,java,arrays,duplicates,Java,Arrays,Duplicates,对于Java实践,我尝试在EmployeesDirectory类中创建一个方法,该方法: 从数组中删除重复项 删除重复项后,数组的长度应相同 非空条目应该在数组的开头形成一个连续的序列,而实际值应该保留条目的记录 重复的意思是:相同的姓名、职位和薪水 这是我目前的代码: 我不确定如何实现这一点-任何帮助将不胜感激 class EmployeeDirectory { private Employee dir[]; private int size; private i

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

  • 从数组中删除重复项
  • 删除重复项后,数组的长度应相同
  • 非空条目应该在数组的开头形成一个连续的序列,而实际值应该保留条目的记录
重复的意思是:相同的姓名、职位和薪水

这是我目前的代码:

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

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;
        }
    }
}

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

另外,为什么不使用
集合
(链接)而不是数组来实现您的目的呢?根据其自身的定义,集合不允许添加重复项,因此它们似乎是合适的解决方案

如果任务状态为“从数组中删除重复项”(即在添加项时不能使用
数组列表
或控件),则可以使用以下方法:

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();
}

不幸的是,我没有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];
}
首先,在
Employee
类中重写
equals
hashCode
方法,如下所示

@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
        });
}
然后您可以使用streamapi
distinct
方法删除重复项

返回由不同元素组成的流(根据 对象。等于此流的(对象))

你可以这样做

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);
输出:(保留空条目和非空条目)


删除重复条目!!您的意思是删除仅具有相同名称的重复员工???@MChaker他们指的是
a.equals(b)==true
Set不总是有用的对象,因为它会破坏元素的顺序。但是,在迭代数组以收集不同对象时,Set很有用。@SashaSalauyou,如果您需要与插入顺序相同的元素顺序,有一个方法可以实现:)使用
LinkedHashSet
您将失去在O(1)中按索引查询项的能力。@SashaSalauyou这是一个很好的观点,但你建议用什么来代替LinkedHashSet呢?我建议对初始数组进行操作,如我在回答中所示,在发现重复项时将项目向左移动。指定单个字符作为引用的名称是一种不好的做法。引用名称应该是有意义的。而且,您可能没有了解到集合的内容。集合不能包含相等的对象。“您可能没有了解集合的内容”-抱歉,我无法继续讨论是一种如此突然的方式…我不是有意冒犯您,但集合本身“跳过”它已经包含的所有对象。此时,您的代码没有意义。阅读文档。SorryGood方法使用
Hashset
存储不同的项+1。但是OP问题说这个
重复的意思是:相同的名字、职位和薪水
,没有相同的对象引用?@MChaker刚刚添加了
hashCode()
equals()
覆盖。@sashasalauou你觉得上面的答案怎么样?我觉得很好(我也喜欢java 8的功能),但是你的
equals()
方法很容易出错,除非
name
position
不能保证为非空。而且您的
hashCode()
非常差,通常由对象的所有非静态属性组合而成。@SashaSalauyou现在呢?好吧,我看到您正在尝试,但是现在如果
this.name==null
other.name==null
呢?实际上,如果其他属性相等,那么这些对象应该相等。但是您的代码将返回false。
@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
        });
}
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