2015-11-21 2 views
1

Je fais l'algorithme Join dans MapReduce. Dans la phase Map, j'ai fait de joinColumn comme clé et le tuple comme valeur. Dans la méthode réduire, j'ai des clés et des valeurs comme (nom de la colonne, ligne). Dans la phase de réduction, j'ai besoin de séparer la "rangée" en deux en fonction de la table à laquelle ils appartiennent.Programmation de réduction de carte: MultiMap écrase les valeurs de clé existantes

J'ai utilisé MultiMap pour cela. Mais le MultiMap écrase la valeur existante. Pour essayer de surmonter cela, je remplace "equals" et "hashcode" mais cela n'a pas résolu le problème.

public void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException{ 

    Multimap<String,Table> entry=LinkedListMultimap.create(); 
    for(Text val : values){ 
     String[] row=val.toString().split(","); 
     Table t = new Table(); 
     t.setTablename(row[0]); 
     t.setColumns(val); 
     entry.put(row[0],t); 
    } 
    for (String k: entry.keySet()){ 
     System.out.println("Key : "+k); 
     Collection<Table> rows=entry.get(k); 
     Iterator<Table> i=rows.iterator(); 
     while(i.hasNext()){ 
      Table t=i.next(); 
      System.out.println(t.getColumns()); 
     } 
    } 
public class Table { 
    private String tablename; 
    private Text columns; 
    public String getTablename() { 
     return tablename; 
    } 
    public void setTablename(String tablename) { 
     this.tablename = tablename; 
    } 
    public Text getColumns() { 
     return columns; 
    } 
    public void setColumns(Text columns) { 
     this.columns = columns; 
    } 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((columns == null) ? 0 : columns.hashCode()); 
     result = prime * result 
       + ((tablename == null) ? 0 : tablename.hashCode()); 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Table other = (Table) obj; 
     if (columns == null) { 
      if (other.columns != null) 
       return false; 
     } else if (!columns.equals(other.columns)) 
      return false; 
     if (tablename == null) { 
      if (other.tablename != null) 
       return false; 
     } else if (!tablename.equals(other.tablename)) 
      return false; 
     return true; 
    } 
} 

Je reçois la sortie suivante:

Key : S 
R, 2, Don, Larson, Newark, 555-3221 
R, 2, Don, Larson, Newark, 555-3221 
Key : R 
R, 2, Don, Larson, Newark, 555-3221 
Key : S 
R, 3, Sal, Maglite, Nutley, 555-6905 
R, 3, Sal, Maglite, Nutley, 555-6905 
Key : R 
R, 3, Sal, Maglite, Nutley, 555-6905 
Key : R 
S, 4, 22000, 7000, part1 
Key : S 
S, 4, 22000, 7000, part1 

Il est Dérogation des valeurs existantes. Quelqu'un peut-il m'aider à régler ce problème?

Répondre

1

Votre problème est que l'objet renvoyé par l'itération de valeurs est réutilisé par l'itérateur. Au lieu d'attribuer simplement la valeur dans setColumns(), vous devez le copier. Quelque chose comme:

public void setColumns(Text columns) { 
    this.columns = new Text(columns.toString()); 
} 
+0

Pouvez-vous élaborer? Je suis juste un débutant – vishnu

+0

@ user2560089 Ajout d'un exemple de code –