2015-05-09 25 views
5

Für Java Praxis Ich versuche, eine Methode in meiner EmployeesDirectory Klasse zu erstellen, dass:doppelte Einträge in Array - Java

  • Entfernt doppelte Einträge aus dem Array
  • Das Array sollte die gleiche Länge nach Entfernen von Duplikaten
  • nicht leeren Einträge sollten eine zusammenhängende Sequenz am Anfang des Arrays macht - und die actualNum sollte eine Aufzeichnung der Einträge halten

Duplizieren Bedeutet: gleichen Namen, Position und Gehalt

Hier ist meine aktuellen Code ist:

Ich bin nicht sicher, wie diese umzusetzen - jede Hilfe würde

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

doppelte Einträge zu entfernen !! Du meinst entfernen doppelte Mitarbeiter mit dem gleichen Namen nur ?? – MChaker

+0

@MChaker sie meinen Objekte, für die 'a.equals (b) == true' –

Antwort

4

Ich würde eher Sie erkannt werden, hat keine eindeutige Methode zum Entfernen von Duplikaten geschrieben. Wenn ich Sie wäre, würde ich nach Duplikaten in add Methode suchen und dann sofort entscheiden, ob ich hinzufügen muss.

Auch warum verwenden Sie nicht Sets (Link für HashSet) anstelle von Arrays für Ihren Zweck? Sets durch ihre eigene Definition disallow Hinzufügen von Duplikaten, so dass sie zu sein scheinen angemessen als Lösung

+0

Set ist nicht immer nützlich, weil es die Reihenfolge der Elemente bricht. Aber Set ist nützlich, wenn das Array zum Sammeln verschiedener Objekte iteriert wird. –

+1

@SashaSalauyou, wenn Sie die gleiche Reihenfolge der Elemente müssen ebenso wie die um sie einzufügen, gibt es eine [LinkedHashSet] (http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashSet .html), um dies zu erreichen :) –

+0

Mit 'LinkedHashSet' verlieren Sie die Möglichkeit, in O (1) Punkt für Punkt abzufragen. –

1

Wenn Ihre Aufgabe Staaten als „Duplikate entfernen aus Array“ (dh Sie können nicht ArrayList oder Steuerung verwenden, wenn Elemente hinzugefügt) können Sie verwenden Sie den folgenden Ansatz:

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

Hier shift Variable speichert Anzahl von Duplikaten im Array gefunden bisher. Jeder einzelne Artikel wird in shift Positionen verschoben, um die Reihenfolge kontinuierlich zu halten, während die anfängliche Bestellung beibehalten wird. Dann werden die verbleibenden Elemente in Nullen geändert.

Um Hash-basierte Sammlungen arbeiten mit Employee Instanzen richtig zu machen, müssen Sie auch hashCode() und equals() Methoden außer Kraft setzen, wie folgt: Leider

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

Das Zuweisen eines einzelnen Zeichens als Name für eine Referenz ist eine schlechte Übung. Referenznamen sollten aussagekräftig sein. Außerdem haben Sie wahrscheinlich nicht verstanden, was die Sets sind. Sets können KEINE gleichen Objekte enthalten. –

+0

* „Du hast wahrscheinlich nicht bekommen, was die Sets sind“ * - sorry, ich kann nicht mehr weiter Diskussion eine solche abrupte Art und Weise ist ... –

+0

ich Sie nicht beleidigen wollte, aber selbst Set „überspringt“ alle Objekte, die es enthält bereits. An diesem Punkt macht Ihr Code keinen Sinn. Lesen Sie die Dokumentation. Entschuldigung –

2

, ich habe die Klasse Employee nicht bekam meinen Code zu überprüfen, aber versuchen Sie dies:

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

Der Code muss die Größe des Arrays nach dem Löschen der Duplikate bleiben. Zu Beginn des Arrays muss es gültige Mitarbeiter geben, am Ende - Nullen. Und vergessen Sie nicht, dies am Anfang Ihres hinzuzufügen.Java-Datei

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

Zu allererst Aufschaltenequals und hashCode Methoden in Employee Klasse wie folgt

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

Dann können Sie Stream-API distinct Methode verwenden Duplikate

Returns zu entfernen ein Strom, der aus den einzelnen Elementen besteht (nach Object.equals (Object)) dieses Streams.

Sie können es wie 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); 

Ausgang: (wobei beide leer und nicht leere Einträge)

John developer 2000.0 
Fres designer 1500.0 
null 
+0

@SashaSalauyou Was halten Sie von der obigen Antwort? – MChaker

+0

Ich denke, es ist ziemlich gut (ich liebe Java 8 Funktionen auch), aber Ihre 'equals()' Methode ist fehleranfällig, es sei denn, 'name' und' position' sind nicht garantiert Nullen. –

+0

und Ihr 'hashCode()' ist sehr schlecht, normalerweise wird es durch alle nicht statischen Eigenschaften des Objekts kombiniert. –

Verwandte Themen