Java 在迭代期间更改 HashMap 键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4235774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing HashMap keys during iteration
提问by lisak
is it possible to change keys of a the same HashMap instance during iteration ? Because map entry set don't have a method entry.setKey(). Now what I can think off is create another HashMap...
是否可以在迭代期间更改同一个 HashMap 实例的键?因为地图条目集没有方法 entry.setKey()。现在我能想到的是创建另一个 HashMap ......
MultipartParsingResult parsingResult = parseRequest(request);
Map<String, String[]> mpParams = parsingResult.getMultipartParameters();
Map<String, String[]> mpParams2 = new HashMap<String, String[]>();
Iterator<Entry<String,String[]>> it = mpParams.entrySet().iterator();
while (it.hasNext()) {
Entry<String,String[]> entry = it.next();
String name = entry.getKey();
if (name.startsWith(portletNamespace)) {
mpParams2.put(name.substring(portletNamespace.length(), name.length()), entry.getValue());
}
else {
mpParams2.put(name, entry.getValue());
}
}
采纳答案by Chandra Patni
You should keep information in other collection to modify it after iteration. You can only remove entry using iterator.remove()during iterator. HashMapcontract forbids mutating it during iteration.
您应该将信息保留在其他集合中以在迭代后对其进行修改。您只能iterator.remove()在迭代器期间使用删除条目。HashMap合同禁止在迭代期间对其进行变异。
回答by Tejas
There are four common types of modification you might want to do to the keys or values in a HashMap.
您可能希望对 HashMap 中的键或值进行四种常见的修改。
- To change a HashMap key, you look up the value object with get, then remove the old key and put it with the new key.
- To change the fields in a value object, look the value object up by key with get, then use its setter methods.
- To replace the value object in its entirely, just put a new value object at the old key.
- To replace the value object with one based on the old, look the value object up with get, create a new object, copy data over from the old one, then put the new object under the same key.
- 要更改 HashMap 键,请使用 get 查找值对象,然后删除旧键并将其放入新键。
- 要更改值对象中的字段,请使用 get 键查找值对象,然后使用其 setter 方法。
- 要完全替换值对象,只需在旧键上放置一个新值对象。
- 要将值对象替换为基于旧的值对象,请使用 get 查找值对象,创建一个新对象,从旧对象复制数据,然后将新对象放在相同的键下。
Something like this example.
像这个例子。
static class Food
{
// ------------------------------ FIELDS ------------------------------
String colour;
String name;
float caloriesPerGram;
// -------------------------- PUBLIC INSTANCE METHODS --------------------------
public float getCaloriesPerGram()
{
return caloriesPerGram;
}
public void setCaloriesPerGram( final float caloriesPerGram )
{
this.caloriesPerGram = caloriesPerGram;
}
public String getColour()
{
return colour;
}
public void setColour( final String colour )
{
this.colour = colour;
}
public String getName()
{
return name;
}
public void setName( final String name )
{
this.name = name;
}
public String toString()
{
return name + " : " + colour + " : " + caloriesPerGram;
}
// --------------------------- CONSTRUCTORS ---------------------------
Food( final String name, final String colour, final float caloriesPerGram )
{
this.name = name;
this.colour = colour;
this.caloriesPerGram = caloriesPerGram;
}
}
// --------------------------- main() method ---------------------------
/**
* Sample code to TEST HashMap Modifying
*
* @param args not used
*/
public static void main( String[] args )
{
// create a new HashMap
HashMap<String, Food> h = new HashMap<String, Food>( 149
/* capacity */,
0.75f
/* loadfactor */ );
// add some Food objecs to the HashMap
// see http://www.calorie-charts.net for calories/gram
h.put( "sugar", new Food( "sugar", "white", 4.5f ) );
h.put( "alchol", new Food( "alcohol", "clear", 7.0f ) );
h.put( "cheddar", new Food( "cheddar", "orange", 4.03f ) );
h.put( "peas", new Food( "peas", "green", .81f ) );
h.put( "salmon", new Food( "salmon", "pink", 2.16f ) );
// (1) modify the alcohol key to fix the spelling error in the key.
Food alc = h.get( "alchol" );
h.put( "alcohol", alc );
h.remove( "alchol" );
// (2) modify the value object for sugar key.
Food sug = h.get( "sugar" );
sug.setColour( "brown" );
// do not need to put.
// (3) replace the value object for the cheddar key
// don't need to get the old value first.
h.put( "cheddar", new Food( "cheddar", "white", 4.02f ) );
// (4) replace the value object for the peas key with object based on previous
Food peas = h.get( "peas" );
h.put( "peas", new Food( peas.getName(), peas.getColour(), peas.getCaloriesPerGram() * 1.05f ) );
// enumerate all the keys in the HashMap in random order
for ( String key : h.keySet() )
{
out.println( key + " = " + h.get( key ).toString() );
}
}// end main
}
I hope this helps
我希望这有帮助
回答by Tolga Y?lmaz
Maybe this helps:
也许这有帮助:
map.put(newkey,map.remove(oldkey));
回答by Elemental
The best thing to do is to copy the map into a new one with the modifications you want, then return this new maps and destroy the old one. I wonder what's the performance impact of this solution however.
最好的办法是将地图复制到带有您想要的修改的新地图中,然后返回这个新地图并销毁旧地图。但是,我想知道此解决方案的性能影响是什么。
回答by Robocide
i got to this thread when i needed to change the keys of the map entries. in my case i have a JSON representation in a Map , meaning it can hold map or list of maps, here is the code:
当我需要更改地图条目的键时,我进入了这个线程。就我而言,我在 Map 中有一个 JSON 表示,这意味着它可以保存地图或地图列表,这是代码:
private Map<String,Object> changeKeyMap(Map<String, Object> jsonAsMap) throws InterruptedException {
Map<String,Object> mapClone = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : jsonAsMap.entrySet()) {
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
Object value = entry.getValue();
if (entry.getValue() instanceof Map) {
value = changeKeyMap((Map) entry.getValue());
} else if (isListOfMaps(entry.getValue())) {
value = changeKeyListOfMaps((List<Map<String, Object>>) entry.getValue());
}
String changedKey = changeSingleKey(entry.getKey());
mapClone.put(changedKey, value);
}
return mapClone;
}
private List<Map<String,Object>> changeKeyListOfMaps(List<Map<String,Object>> listOfMaps) throws InterruptedException {
List<Map<String,Object>> newInnerMapList = new ArrayList<>();
for(Object singleMapFromArray :listOfMaps){
Map<String,Object> changeKeyedMap = changeKeyMap((Map<String, Object>) singleMapFromArray);
newInnerMapList.add(changeKeyedMap);
}
return newInnerMapList;
}
private boolean isListOfMaps(Object object) {
return object instanceof List && !((List) object).isEmpty() && ((List) object).get(0) instanceof Map;
}
private String changeSingleKey(String originalKey) {
return originalKey + "SomeChange"
}

