title: Reducer values in MapReduce need to be copied, otherwise subject to modification?
body: <p>In a MapReduce application, I have this arbitrary WritableComparable implementation called AnonymousPair and I have noticed this</p>
  
  <pre><code>import com.google.common.collect.MinMaxPriorityQueue;
  
  public static class MyReducer extends Reducer&lt;LongWritable, AnonymousPair, LongWritable, Text&gt; {
      @Override
      protected void reduce(LongWritable key, Iterable&lt;AnonymousPair&gt; values, Context context) throws IOException, InterruptedException { 
          // ...
          MinMaxPriorityQueue&lt;AnonymousPair&gt; pQueue = MinMaxPriorityQueue
                  .orderedBy(new AnonymousPair().comparator())
                  .maximumSize(Constants.MaxKeywords)
                  .create();
  
          for(AnonymousPair val : values) {
              pQueue.add(new AnonymousPair(val)); // No problem with copy constructor
              // pQueue.add(val);                 // Wrong! Every element in pQueue will be the same 
          }
      }
  }
  </code></pre>
  
  <p>If I don't use 'copy constructor', every element in the pQueue ends up being the same. Could anyone help me understand this? Thanks!
  My guesses are</p>
  
  <ol>
  <li>Reference to Reducer Values elements subject to modification. It is somewhere in the doc but I missed it. </li>
  <li>I'm using Google Guava MinMaxPriorityQueue wrongly</li>
  <li>Or something wrong with my WritableComparable implementation</li>
  </ol>
  
  <p>My AnonymousPair implementation </p>
  
  <pre><code>    public static class AnonymousPair implements WritableComparable&lt;AnonymousPair&gt; {
          private String a = "";
          private Float b = 0f;
          public AnonymousPair() {}
          public AnonymousPair(String a, Float b) {this.a = a; this.b = b;}
          public AnonymousPair(AnonymousPair o) {this.a = o.a; this.b = o.b;}
  
          public Comparator&lt;AnonymousPair&gt; comparator() {return new AnonymousPairComparator();}
  
          class AnonymousPairComparator implements Comparator&lt;AnonymousPair&gt; {
              @Override
              public int compare(AnonymousPair o1, AnonymousPair o2) {
                  Float diff = o1.b - o2.b;
                  if(diff == 0) {
                      return 0;
                  }
                  if(diff &lt; 0) {
                      return 1;   // Reverse order
                  } else {
                      return -1;
                  }
  
              }
          }
  
          @Override
          public int compareTo(AnonymousPair o) {
              int temp = this.a.compareTo(o.a);
              if(temp == 0) {
                  return -this.b.compareTo(o.b);
              } else {
                  return temp;
              }
          }
  
          // More overriding...
      }
  </code></pre>