Java: Generic keyvalue like C#
我现在在Java中寻找一种方法来做一些类似C++的事情。例如,在ASP MVC中,您可以编写:
1
| DoMethod(new {key = value, another = value2}); |
在Java中有什么好的方法吗?我只试过一个数组:new object[] {value, value...}。不过,这样我就不能只得到键值。
我知道你能做到:
1 2 3 4
| HashMap <String, object > map = new HashMap();
map. put("key", "value");
map. put("anoter", "value2");
DoMethod (map ); |
不幸的是,如果你需要经常这样做,那是一种很麻烦的方式。
干杯!
- 没有;Java不支持匿名类型。
- 您需要什么样的键类型和值类型?
- 关键是字符串。值是一个对象
不要再改造轮子。如果您可以自由使用第三方libs,您可以尝试Google guava,它提供了没有静态初始值设定项和子类的强类型方法、代理Entry/Pair类或可能看起来不安全的变量参数:
使用生成器模式:
1 2 3 4 5
| final Map <String, Object > map = new ImmutableMap. Builder<String, Object >()
. put("key", "value")
. put("anoter", "value2")
. build();
DoMethod (map ); |
或者,如果条目数达到5,甚至是更短的方法(请参见重载,为什么所有这些map-factory方法都是类型安全的):
1 2
| final Map <String, Object > map = ImmutableMap. <String, Object >of ("key", "value", "anoter""value2");
DoMethod (map ); |
- 我投了反对票,因为这可能是初始化映射的最佳方法。我给出了更复杂的答案,因为我相信OP会更普遍地询问如何将"匿名类型"作为参数传递。答案是你不能这么做,但是你可以写一些简单的类,然后通过它们。
尝试:
4
阐述:
outer {}块表示该实例是一个匿名类,扩展了HashMap。
内部{}块表示复制到匿名类的构造函数的代码。
- 我认为,双括号初始化模式最终应该被认为是有害的:生成了另一个类;它只适用于非final类;它可能导致(反)序列化问题。另外,在您的例子中,没有什么"复制"到匿名类构造函数:构造函数实际上几乎是空的(只是super构造函数委托)。内部大括号实际上只包含在构造函数调用之前调用的类初始值设定项。
- 从DOCS.Oracle .COM/JavaSe/TutoRale/Java/JavaOO/NIALAL.HTML:"Java编译器将初始化器块复制到每个构造函数中"。我同意这不是一种有效的方法(我不知道.NET版本的效率),但它是一种语言特性,在我看来,它更接近于OP所要求的(语法方面),然后是这里的任何其他答案。
- 这几天对我来说又是一个伟大的发现。我只是一直相信类初始值设定项是JVM的一级公民,就像构造函数一样。对于finallyIES来说也是一样的——据我所知,它们也被复制了(这就是初始化器不能通过反射访问的原因)。我很困惑"Java编译器将初始化器块复制到每个构造函数"(那时我不确定调用图)。现在我知道了,谢谢!:)
- 我不知道.NET版本——在C中,它只是语法糖。请参阅stackoverflow.com/questions/459652/&hellip;--它只是链接Add方法调用。
一个简单的解决方案是使用一对参数。
1 2 3 4 5 6 7 8 9
| public static <K, V > Map <K, V > newMap (K key, V value, Object... keysAndValues) {
Map <K, V > temp = new LinkedHashMap <K, V >();
temp. put(key, value );
for (int i = 0; i < keysAndValues. length; i +=2)
temp. put((K ) keysAndValues [i ], (V ) keysAndValues [i +1]);
return temp ;
}
Map <String, Integer > map = newMap ("Key1", 1, "Key2", 2); |
- 你每次需要增加2个I…
- @pbabcdefp感谢您的更正。
- 没关系。出于兴趣。你觉得这种事情怎么样(你的解决方案还是我的解决方案)?你推荐它吗?或者我们应该等到语言有了合适的地图文本?
- 你可以等待,但是你可能在等待这些特性在Java中成为主流之前等待一段时间。
你不能直接用Java做这种事情,但是你可以用VARARGS和EDCOX1的0个类来模拟它。首先创建一个Pair类,如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Pair<T, U> {
public static <T, U> Pair<T, U> of(T t, U u) {
return new Pair<T, U>(t, u);
}
private final T t;
private final U u;
private Pair(T t, U u) {
this.t = t; this.u = u;
}
public T first() { return t; }
public U second() { return u; }
} |
然后可以使用varargs编写方法:
1 2 3 4 5 6 7
| static <K, V> Map<K, V> initialiseMap(Pair<K, V>... entries) {
Map<K, V> temp = new HashMap<K, V>();
for (Pair<K, V> pair : entries) {
temp.put(pair.first(), pair.second());
}
return temp;
} |
例如,您可以通过编写来初始化Map。
2
Java本身没有任何类似的东西。不过,您可能可以在其他JVM语言中找到这些特性。如果您有选择的自由,并且您喜欢动态类型和相关特性,同时保留类似Java的语法,请检查Groovy。
- 我的服务器是用Java编写的,不过还是要谢谢你:
- 哦,是的,所有的JVM语言都被编译成相同的字节码,所以不会失去兼容性。在运行时,您不知道该类是用什么语言编写的,也不在乎。具体来说,Groovy实际上是Java,具有更多的特性,因为几乎所有有效的Java代码都是有效的Groovy代码。Java是一种企业语言,因此它的核心通过设计慢慢演变。快速的创新留给了其他的JVM语言。