Java - 是否可以用 1 行代码向地图内的地图添加键/值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1363101/
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
Java - is adding a key/value to a map within a map in 1 line of code possible?
提问by Tony Stark
I have HashMap 1, which contains 5 keys, all of which have Hashmaps as values. I want to add key/value pairs to these sub-Maps.
我有 HashMap 1,它包含 5 个键,所有键都具有 Hashmap 作为值。我想向这些子地图添加键/值对。
map1.get(subCategoryMap).put(newKey, newValue);
My thinking is:
我的想法是:
map1.get(subCategoryMap);
returns another map. I could split this line into two lines and have:
返回另一张地图。我可以把这条线分成两行,并有:
map2 = map1.get(subCategoryMap);
map2.put(newKey, newValue);
But I would MUCH prefer to do it in one step. Which is why I am trying
但我更愿意一步完成。这就是为什么我要尝试
map1.get(subCategoryMap).put(newKey, newValue);
This doesn't work (doesn't like .put() on an object). Is it possible to access the sub-Map and add to it in the same line of code like I am above, or do I need to split this into 2 lines?
这不起作用(不喜欢对象上的 .put() )。是否可以像上面一样访问子地图并在同一行代码中添加到它,或者我是否需要将其分成两行?
采纳答案by cletus
With generics you can:
使用泛型,您可以:
Map<String, Map<String, String>> map1 = ...
map1.get(category).put(subcategory, value);
If the maps aren't generic:
如果地图不是通用的:
Map map1 = ...
((Map)map1.get(category)).put(subcategory, value);
回答by Andrew Duffy
((Map)map1.get(subCategoryMap)).put(newKey, newValue);
Or, use generics:
或者,使用泛型:
Map<X, Map<Y,Z>> map1;
...
map1.get(subCategoryMap).put(newKey, newValue);
However, both techniques will fail with NullPointerException
if map1
doesn't contain a mapping for subCategoryMap
.
但是,NullPointerException
如果map1
不包含subCategoryMap
.
回答by Thomas Owens
If you aren't using Generics, then a HashMap stores and retrieves the keys and values as Object, so you might need to cast, which would look something like this:
如果您不使用泛型,则 HashMap 将键和值作为对象存储和检索,因此您可能需要进行强制转换,如下所示:
((HashMap)map1.get(subCategoryMap)).put(newKey, newValue);
However, it would be helpful if you provided more code.
但是,如果您提供更多代码会有所帮助。
回答by Powerlord
If you use Generic collections, then your code should work as written. Otherwise, you need to add in the appropriate casts into your single line.
如果您使用通用集合,那么您的代码应该像编写的那样工作。否则,您需要将适当的强制转换添加到您的单行中。
回答by erickson
As long as map1
is declared something like Map<OuterKey, Map<InnerKey, MyValue>>
, a one-liner will work. However, you need to be careful about what happens if subCategoryMap
doesn't exist in map1
—a one-liner will raise a NullPointerException
.
只要map1
声明了类似的东西Map<OuterKey, Map<InnerKey, MyValue>>
,一个单线就可以工作。但是,您需要注意如果subCategoryMap
不存在会发生什么map1
- 单行代码会引发NullPointerException
.
回答by Nettogrof
You can use ((HashMap)map1.get(subCategoryMap)).put(newKey, newValue);
您可以使用 ((HashMap)map1.get(subCategoryMap)).put(newKey, newValue);
Also, if you are using Java 5 or Java 6, you can use generic to avoid the cast in HashMap
此外,如果您使用的是 Java 5 或 Java 6,则可以使用 generic 来避免强制转换 HashMap
回答by Fabian Steeg
Works fine if you use generics:
如果您使用泛型,效果很好:
Map<String,Map<String,Integer>> map = new HashMap<String,Map<String,Integer>>();
map.put("Test", new HashMap<String,Integer>());
map.get("Test").put("Some", 1);
回答by Bill K
Just an aside (I'd make this a comment but I think it will be slightly long)...
顺便说一句(我会把它作为评论,但我认为它会有点长)......
It feels very good for a programmer to be able to get a single conceptual operation on one line. To the programmer (at the time) it feels more readable, logical and just feels right.
对于一个程序员来说,能够在一行中得到一个概念性的操作,感觉非常好。对于程序员(当时)来说,它感觉更具可读性、逻辑性并且感觉正确。
It is almost never a good thing. For one thing, later it will be harder to parse than two lines--even if your gut reaction now is that it is more readable. Also--the more operations on one line, the harder it is to debug.
这几乎从来都不是一件好事。一方面,以后会比两行更难解析——即使你现在的直觉反应是它更具可读性。此外 - 一行上的操作越多,调试就越困难。
For readability, I'd say the Generics solution is about as much as I'd put on a single line--for the casting solution I'd break it down into two lines; I'd also break it down into multiple lines if either of the parameters were operations instead of just simple variables.
为了可读性,我想说泛型解决方案和我放在一行中的一样多——对于铸造解决方案,我将它分成两行;如果其中一个参数是操作而不是简单的变量,我也会将其分解为多行。
I know a lot of people won't agree with this and to tell you the truth I tend to put quite a bit on one line at first, but what I've noticed is that at the first sign of trouble or any confusion, it makes my life easier to break everything down into separate statements with clearly named variables.
我知道很多人不会同意这一点,老实说我一开始倾向于把很多东西放在一条线上,但我注意到的是,在出现麻烦或任何混乱的第一个迹象时,它让我的生活更轻松地将所有内容分解为具有明确命名变量的单独语句。
At least as important--in cases with nested collections, I will often wrap the collections in a different object as well. This would be interesting in your case--the call would become a little more clear.
至少同样重要——在嵌套集合的情况下,我通常也会将集合包装在不同的对象中。这在您的情况下会很有趣 - 呼叫会变得更加清晰。
dataHolder.put(category, newKey, newVale);
Hides the mechanics of the nesting of the collections (which otherwise can be complex to remember correctly and easy to screw up) and makes your intent much clearer.
隐藏集合嵌套的机制(否则可能很难正确记住并且容易搞砸)并使您的意图更加清晰。
This pattern of wrapping (Not extending but encapsulating) nested collections feels strange at first but I really suggest you just give it a try--it really cleans up a LOT of code, makes everything much safer adds to everybody's comprehension, changes a "Collection" to a business object (where you can place business methods--a refactoring you will appreciate almost immediately), and just generally helps your code all over.
这种包装(不是扩展而是封装)嵌套集合的模式一开始感觉很奇怪,但我真的建议你试一试——它确实清理了很多代码,让一切变得更安全,增加了每个人的理解,改变了一个“集合" 到一个业务对象(您可以在其中放置业务方法——您几乎会立即欣赏到的重构),并且通常对您的代码有帮助。