2017-06-28 2 views
0

Ich habe ein besonderes Problem der Reorganisation einer Reihe von Daten, die ich habe. Derzeit meine Daten in einem Arraylist der folgenden Klasse gehalten:Collapsing ArrayListe von Objekten basierend auf zwei Attributen, um eindeutige Mengen zu generieren

class MyRecord { 
    private String location; 
    private ArrayList<EmployeeCategory> employeeCategory;} 

class EmployeeCategory { 
    private String category; 
    private String employee; 
} 

wie ArrayList<MyRecord> myRecordList;

Der Dateninhalt Ich habe sieht wie folgt aus (ich es in irgendeiner JSONlike Struktur vorstelle):

{location: "Houston", {category: "purchasing", employee: "John"}}, 
{location: "Houston", {category: "sales", employee: "John"}}, 
{location: "Houston", {category: "purchasing", employee: "Hank"}}, 
{location: "Houston", {category: "field operations", employee: "Hank"}}, 
{location: "Houston", {category: "sales", employee: "Jane"}}, 
{location: "Houston", {category: "purchasing", employee: "Jane"}}, 
{location: "Houston", {category: "human resources", employee: "Jane"}}, 
{location: "Dallas", {category: "purchasing", employee: "Matt"}}, 
{location: "Dallas", {category: "field operations", employee: "Matt"}}, 
{location: "Dallas", {category: "human resources", employee: "Todd"}}, 
{location: "Dallas", {category: "field operations", employee: "Todd"}}, 
{location: "Dallas", {category: "sales", employee: "Todd"}}, 
{location: "Dallas", {category: "purchasing", employee: "June"}}, 
{location: "Dallas", {category: "human resources", employee: "June"}} 

ich möchte, dass die Daten vereinfachen und sie in die Arraylist der folgenden Klasse reorganisieren:

class MyCollapsedRecord { 
    private String location; 
    private String name; 
    private ArrayList<String> employee; 
} 

so dass die Daten in der folgenden Form sein würde:

{location:"Houston", category:"purchasing", employee:["John", "Hank", "Jane"]}, 
{location:"Houston", category:"sales", employee:["John", "Jane"]}, 
{location:"Houston", category:"field operations", employee:["Hank"]}, 
{location:"Houston", category:"human resources", employee:["Jane"]}, 
{location:"Dallas", category:"purchasing", employee:["Matt", "June"]}, 
{location:"Dallas", category:"field operations", employee:["Matt", "Todd"]}, 
{location:"Dallas", category:"human resources", employee:["Todd", "June"]}, 
{location:"Dallas", category:"sales", employee:["Todd"]} 

denke ich, beste Strategie eindeutige Datensätze auf den Paaren der Lage und Kategorie basieren Erzeugung würde bedeuten. Ich habe versucht, LinkedHashSet beim Überschreiben von Equals und HashValue-Methoden zu verwenden, aber ich glaube, dass meine Datenstrukturen für diese Art von Anwendung ein wenig zu komplex sind. Ich denke, dass ich einen manuelleren Ansatz mit verschachtelten For-Schleifen wie dieser algorithm haben müsste, aber ich konnte meinen Kopf nicht umschließen, um es zu meinem komplexeren Fall zu ändern.

Hier ist mein Versuch einer Reorganisation bisher:

ArrayList<MyRecord> myRecordArrayList = new ArrayList<>(); 
//Load data to myRecordArrayList 
ArrayList<CollapsedRecord> myCollapsedArrayList = new ArrayList<>(); 

for (int i = 0; i < myRecordArrayList.size(); i++) { 
    boolean isDistinctLocation = false; 
    for (int j=0; j < i; j++) { 
     if (myRecordArrayList.get(i).getLocation().equals(myRecordArrayList.get(j).getLocation())) { 
      isDistinctLocation = true; 
      for (int m = 0; m < myRecordArrayList.get(i).getEmployeeCategory().size(); m++) { 
       boolean isDistinctCategory = false; 
       for (int n = 0; n < m; n++) { 
        if (myRecordArrayList.get(i).getEmployeeCategory().get(m).getCategory().equals(myRecordArrayList.get(i).getEmployeeCategory().get(n).getCategory())) { 
         isDistinctCategory = true; 
         CollapsedRecord tempCollapsedRecord = new CollapsedRecord(); 
         tempCollapsedRecord.setLocation(myRecordArrayList.get(i).getLocation());       tempCollapsedRecord.setCategory(myRecordArrayList.get(i).getEmployeeCategory().get(m).getCategory());  
        } 
       } 
      }  
      break; 
     } 
    } 
    if (!isDistinctLocation) { 
     System.out.println(myRecordArrayList.get(i).getLocation()); 
    }  
} 

Wie kann es geschehen?

+0

* I beste Strategie denken eindeutige Datensätze basieren würde bedeuten Erzeugung auf die Paare von Ort und Kategorie. *: In der Tat. Was ist der Code, den du versucht hast? –

+1

Ich habe meinen Code hinzugefügt. Es wurde ziemlich verwirrt in meinem Kopf, dass ich eine Pause brauche, bevor ich es wieder ansehe. – Naci

Antwort

1

Ihr Code nicht auf die Strategie basiert, die Sie denken, ist die richtige:

  • einen Schlüssel definieren, der Standort zusammengesetzt und die Kategorie, die Definition hashCode und equals;
  • Verwenden Sie diesen Schlüssel, um alle mit diesem Schlüssel verknüpften Mitarbeiter zu speichern.

genau das zu tun, und es wird viel einfacher:

public final class Key { 
    private final String location; 
    private final String category; 

    // TODO constructor, getters, equals and hashCode 
} 

Und jetzt benutzen Sie einfach eine Karte:

Map<Key, List<String>> employeesByKey = new HashMap<>(); 
for (MyRecord record : myRecordList) { 
    for (EmployeeCategory ec : record.getEmployeeCategories()) { 
     Key key = new Key(record.getLocation(), ec.getCategory()); 
     employeesByKey.computeIfAbsent(key, k -> new ArrayList<String>()).add(ec.getEmployee()); 
    } 
} 

List<MyCollapsedRecord> result = 
    employeesByKey.stream() 
        .map(entry -> new MyCollapsedRecord(entry.getKey().getLocation(), entry.getKey().getCategory(), entry.getValue())); 
        .collect(Collectors.toList()); 
+0

Wie definierst du den hashCode basierend auf zwei Variablen? Auch habe ich keine Klasse von Mitarbeiter verwendet, würde ich Karte > MitarbeiterByKey, richtig? – Naci

+1

Ja, das war ein Tippfehler. Für den hashCode: 'return Objects.hash (location, category)'. Sie können Ihre IDE auch darum bitten, sie für Sie zu erstellen. –

+0

Im zweiten Teil ('map (entry -> new MyCollapsedRecord (key.getLocation(), key.getCategory(), value))) funktioniert nicht. Die Variable "key" wird möglicherweise nicht initialisiert. Und was soll (Wert) sein? – Naci

Verwandte Themen