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. HashMap
contract 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"
}