替换hashmap java中的重复值

替换hashmap java中的重复值,java,hashmap,text-files,key-value,Java,Hashmap,Text Files,Key Value,我有一个hashmap,其中包含学生id作为键和一些字符串作为值 Map<Integer, String> data = new HashMap<Integer, String>(); 我想在映射中找到重复的值,并用整数值替换它们。i、 我想要一张像这样的地图 1 1 2 2 3 1 4 3 5 2 6 1 i、 e.映射shud选择第一个值(a),找到该值的所有键,然后将这些键的值替换为1。然后选择第二个值(b),找到所有关键点并将其替换为2,依此类推。我正在读取的

我有一个hashmap,其中包含学生id作为键和一些字符串作为值

Map<Integer, String> data = new HashMap<Integer, String>();
我想在映射中找到重复的值,并用整数值替换它们。i、 我想要一张像这样的地图

1 1
2 2
3 1
4 3
5 2
6 1
i、 e.映射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”,使用另一个循环更新值为“a”的所有条目。

首先需要了解的是,HashMap中没有“first”值。如果希望根据键对其进行排序,则应使用
TreeMap

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

//设置oldValue到newValue的映射
HashMap valueMap=。。。;
int i=0;
for(字符串oldValue:data.values()){
如果(!valueMap.contains(oldValue)){
valueMap.put(oldValue,+i);
}
}
//替换数据中的所有内容
对于(Map.Entry-dataEntry:data.entrySet()){
finalMap.put(dataEntry.getKey(),valueMap.get(dataEntry.getValue());
}

创建另一个映射以包含要生成的新值。(这是一个映射,因此您可以快速查找值)。当您浏览原始映射时,请在新映射中查找条目。如果找不到值,请创建一个新映射,可能使用递增的整数。

我不太明白您的意思“我正在读取的文件太大,因此我无法通过指定每个键来手动替换所有键。”如果文件“太大”,则您将无法将哈希表放入主内存(或任何映射或列表数据结构).因此,忽略这一点,在我看来,简单的解决方案是维护您的值的散列:

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;
}
private int currIntVal=1;
私有最终映射idToValue=
新HashMap(DEF_ID_SIZE);
专用最终地图valToInt=
新HashMap(定义值大小);
私有void addMapping(最终int-id,最终字符串值){
put(id,getIntValue(value));
}
私有int getIntValue(最终字符串值){
整数val=valToInt.get(值);
if(val==null){
val=currIntVal++;
valToInt.put(值,val);
}
返回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");
    }
}
公共静态最终字符串A_PLUS_GRADE=“A+”;
公共静态最终字符串A_GRADE=“A”;
公共静态最终字符串A_减_GRADE=“A-”;
...
私有最终映射idToGrade=
新HashMap(DEF_ID_SIZE);
私有void addMapping(最终整数id、最终字符串等级){
最终字符串UPPER_GRADE=GRADE.toUpperCase();
开关(UPPPER_等级){
案例A加等级:idToGrade.put(id,A加等级);
中断;//或返回;
案例A_等级:idtoGrade.put(id,A_等级);
打破
案例A减等级:idToGrade.put(id,A减等级);
打破
...
默认值:抛出新的RuntimeException(级别+“是无法识别的级别”);
}
}

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

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

      }
}
}
公共类示例{
公共静态void main(字符串[]args){
Map finalMap=newtreemap();
Map Map=newtreemap();
地图.付诸表决(1,“a”);
图.put(2,“b”);
地图.付诸表决(3,“a”);
图.put(4,“c”);
地图放置(5,“b”);
地图.付诸表决(6,“a”);
Map setOfValues=newtreemap();
整数计数=0;
/**
*构建一组值。
*/
对于(Map.Entry:Map.entrySet()){
如果(!setOfValues.containsKey(entry.getValue())){
计数++;
setOfValues.put(entry.getValue(),count);
}
}
/**
*替换值。
*/
对于(Map.Entry:Map.entrySet()){
finalMap.put(entry.getKey(),setOfValues.get(entry.getValue());
}
/**
*打印值。
*/
对于(Map.Entry:finalMap.entrySet()){
System.out.println(entry.getKey()+“-”+entry.getValue());
}
}
}

“第一个”值。这意味着什么?HashMap中没有“第一个”值。如何确定整数值应该是什么?你不能在新值到达时就计算出来吗?@Jared..我只想插入从1开始递增的整数值。我只想替换值(字符串)使用hashmap中的整数值。如果您唯一的数据是字母a、b、c,并且您希望将它们替换为1、2、3等,则以下内容可能会有所帮助(替换为ASCII值)。代码位于下一个注释中。for(Map.Entry:Map.entrySet()){finalMap.put(Entry.getKey(),((int)Entry.getValue().charAt(0))-96);}我的错,最后一行应该是根据条目的值从valueMap中获取的。答案中已修复。(但我不是要给您提供代码供您复制,我希望您理解原理并亲自编写:P)
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;
}
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");
    }
}
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());

      }
}
}