替换hashmap java中的重复值

时间:2014-12-02 02:30:58

标签: java hashmap text-files key-value

我有一个hashmap,其中包含student id作为键,一些字符串作为value。

Map<Integer, String> data = new HashMap<Integer, String>();

它包含

等数据
1 a
2 b
3 a
4 c
5 b
6 a

我想在map中找到重复的值,并用整数值替换它们。即我想要一张像

这样的地图
1 1
2 2
3 1
4 3
5 2
6 1

即。 map shud选择第一个值(a),找到该值的所有键,然后用1替换这些键的值。然后选择第二个值(b)找到所有键并用2替换它们,依此类推。我正在阅读的文件太大,所以我不能通过指定每个键手动替换所有键。那么,到目前为止我所尝试的是

Map<Integer,Integer> finalmap = new HashMap<Integer,Integer>();
int a=0;
     List mapkey = new ArrayList(data.keySet());
     List mapval = new ArrayList(data.values());
     Iterator valit = mapval.iterator();
     while(valit.hasNext()){
         a=a+1;
         Object valuet = valit.next();

         Iterator keyit = mapkey.iterator();
         while(keyit.hasNext()){
             Object keyt = keyit.next();

             String comp1 = data.get(keyt).toString();
             String comp2 = valuet.toString();
             if(comp1.equals(comp2)){
                 finalmap.put((String)keyt,a);
             }

         }

     }  

但这并没有给我正确的输出。它不是以a = 1开头。我想可能它首先计算a的所有递增值。我有一个包含1000条记录的文本文件。我得到的输出是

1 1000
2 987
3 1000
4 298
5 987
6 1000

我不知道我哪里错了。请帮我解决这个问题。 谢谢

5 个答案:

答案 0 :(得分:4)

首先需要了解的是,HashMap中没有“第一”值。如果您希望根据密钥进行排序,则应使用TreeMap代替。

如果您不关心该排序,并且您需要的只是相同的整数来替换相同的值,那么有很多方法可以做。一种方法是(代码不准确,但应该证明这个想法):

// setup a map of oldValue to newValue
HashMap<String, Integer> valueMap = ...;
int i = 0;
for (String oldValue : data.values()) {
    if ( ! valueMap.contains(oldValue )) {
        valueMap.put(oldValue, ++i);
    }
}

// replace everything in data
for (Map.Entry<Integer, String> dataEntry : data.entrySet()) {
    finalMap.put(dataEntry.getKey(), valueMap.get(dataEntry.getValue());
}

答案 1 :(得分:3)

您可以尝试以下程序,我们在其中构建一组值然后替换。

public class Sample {

public static void main(String[] args) {
    Map<Integer,Integer> finalMap = new TreeMap<Integer, Integer>();
    Map<Integer,String> map = new TreeMap<Integer, String>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "a");
    map.put(4, "c");
    map.put(5, "b");
    map.put(6, "a");

      Map<String,Integer> setOfValues = new TreeMap<>();

      int count = 0 ;
       /**
       * Build set of values.
       */
      for(Map.Entry<Integer,String> entry : map.entrySet()){
          if(!setOfValues.containsKey(entry.getValue())){
              count++;
              setOfValues.put(entry.getValue(), count);
          }
      }
      /**
       * Replace values.
       */
      for(Map.Entry<Integer,String> entry : map.entrySet()){
          finalMap.put(entry.getKey(), setOfValues.get(entry.getValue()));
      }
      /**
       * Print values.
       */
      for(Map.Entry<Integer,Integer> entry : finalMap.entrySet()){
          System.out.println(entry.getKey()+" - "+entry.getValue());

      }
}
}

答案 2 :(得分:1)

创建另一个Map以包含要生成的新值。 (这是一张地图,因此您可以快速查找值)。在浏览原始地图时,请在新地图中查找条目。找不到值时,创建一个新值,可能是增加的int。

答案 3 :(得分:0)

您需要为此作业使用两个单独的内部循环。使用地图上的第一个循环查找某个值的数字,例如“a”,使用另一个循环来更新其值为“a”的所有条目。

答案 4 :(得分:0)

我不太明白你的意思&#34;我正在阅读的文件太大,所以我无法通过指定每个密钥来手动替换所有密钥。&#34; 如果文件太大而且#34;那么你就不应该将哈希表放入主内存(或任何地图或列表数据结构)。所以无视这一点,在我看来,简单的解决方案是保持你的价值观的哈希值。值:

private int currIntVal = 1;

private final Map<Integer, Integer> idToValue = 
    new HashMap<Integer, Integer>(DEF_ID_SIZE);

private final Map<String, Integer> valToInt = 
    new HashMap<String, Integer>(DEF_VALUES_SIZE);

private void addMapping(final int id, final String value){
    idTovalue.put(id, getIntValue(value));
}

private int getIntValue(final String value){
    Integer val = valToInt.get(value);
    if(val == null){
        val = currIntVal++;
        valToInt.put(value, val);
    }

    return val;
}

基于您为学生ID分配字母成绩这一事实,最有可能最好的解决方案是简单地列举所有可能的成绩,例如:

public static final String A_PLUS_GRADE = "A+";
public static final String A_GRADE = "A";
public static final STring A_MINUS_GRADE = "A-";
...

private final Map<Integer, String> idToGrade = 
    new HashMap<Integer,String>(DEF_ID_SIZE);

private void addMapping(final int id, final String grade){
    final String UPPER_GRADE = grade.toUpperCase();
    switch(UPPPER_GRADE){
    case A_PLUS_GRADE: idToGrade.put(id, A_PLUS_GRADE);
        break; // or return;
    case A_GRADE: idtoGrade.put(id, A_GRADE);
        break;
    case A_MINUS_GRADE: idToGrade.put(id, A_MINUS_GRADE);
        break;
    ...
    default: throw new RuntimeException(grade + " is an unrecognized grade");
    }
}