我有一个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
我不知道我哪里错了。请帮我解决这个问题。 谢谢
答案 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");
}
}