RandomMath
RandomMath

Reputation: 691

Removing Duplicate Entries in Array - Java

For Java practice, I am trying to create a method inside my EmployeesDirectory Class that:

Duplicate Means: Same Name, Position and Salary

Here is my Current Code:

I am unsure on how to implement this - any help would be appreciated

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

Upvotes: 5

Views: 1512

Answers (4)

MChaker
MChaker

Reputation: 2649

First of all, Override equals and hashCode methods in Employee class as follow

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

Then you can use Stream API distinct method to remove duplicates

Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.

You can do it like so

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

Output: (keeping both empty and non-empty entries)

John developer 2000.0
Fres designer 1500.0
null

Upvotes: 4

Alex Salauyou
Alex Salauyou

Reputation: 14338

If your task states as "remove duplicates from array" (i. e. you cannot use ArrayList or control when adding items), you can use the following approach:

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

Here, shift variable stores number of duplicates found in the array so far. Every distinct item is moved to shift positions left in order to make sequence continuous while keeping initial ordering. Then remaining items are altered to nulls.

To make hash-based collections work with Employee instances correctly, you also need to override hashCode() and equals() methods as follows:

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

Upvotes: 1

Lysenko Andrii
Lysenko Andrii

Reputation: 496

Unfortunately, I have not got the Employee class to verify my code, but try this:

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

The code must remain the size of array after deletion the duplicates. At the beginning of array there must be valid Employees, at the end - nulls. And don't forget to add this at the beginning of your .java file

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

Upvotes: 2

Lysenko Andrii
Lysenko Andrii

Reputation: 496

I'd rather you did not write a distinct method for removing duplicates. If I were you, I would search for duplicates in add method and then instantly decide whether I need to add Employee.

Also, why don't you use Sets (link for HashSet) instead of arrays for your purpose? Sets by their own definition disallow adding duplicates, so they seem to be appropriate as a solution

Upvotes: 4

Related Questions