在java中,我应该如何创建一个Map<String,String>
具有不可修改键的,同时保持值可修改。
我想Map<String,String>
通过一个界面将其交给其他人添加/更改 Map 值,但不能更改 Map 键。
更高级别问题的背景是我有变量名列表/集(具有树状结构)(表示为 java 字符串),我希望 java 接口另一侧的代码能够填充别名(也字符串)用于每个变量名称。我想有这个接口的多个实现,所以命名树层次结构可以是别名不同的方式来适应不同的情况。让接口实现填充Map<String,String>
一堆已经设置好的键(并且可能包含值的默认值)并允许它修改值(但不是键),似乎是最好的方法。我正在创建名称和别名之间的映射,所以Map<>
很有意义。
回到较低层次的问题。我希望我的代码类似于:
public class MyClass
{
public interface IMyMapper
{
void build(Map<String,String> mapping);
}
IMyMapper mapper;
// How I'd like to use it
void work()
{
Map<String,String> map ;
// Magic something like Collections unmodifiableMap, but only for keys
// Maybe my question should be how this magic for UnmodifiableMap works, so I could reproduce it??
mapper.build(map);
// Because Maps<> are by reference, changed they made (to the values) would be reflected here
}
}
public class TheirClass implements MyClass.IMyMapper
{
@Override
public void build(Map<String,String> mapping)
{
// use mapping like Map<String,String> without extra/foreign classes
// but not be able to modify the Map keys
// only be able to change the Map values
// Should be able to use all of the awesome Map stuff, like foreach, values, compute
}
}
我知道有,Collections unmodifiableMap(Map<> m)
但这也使值不可修改。如果我的值是可变对象,那么我可以修改它们,但我想坚持使用Strings
(避免使用 set/get 为单个字符串成员创建类,或使用公共字符串成员创建类结构类)。
AKA,我想避免创建我自己的可变类值,并用于Collections unmodifiableMap()
使键和value references
不可修改:
// mutable reference to a String
public class ExtraWorkForForEveryone
{
public String value;
public void setValue(String value) { ... }
public String getValue() { ... }
}
// and then use:
void work()
{
Map<String,ExtraWorkForEveryone> map;
map = Collections.unmodifiableMap( ... );
// because Collections.unmodifiableMap() only stops them from changing the Map references,
// the interfacer could still change the ExtraWorkForEveryone internals.
// so they could not change keys refs or value refs, but they could change value data.
mapper.build(map);
// Because Maps<> are by reference, changed they made (to the values) would be reflected here
}
我可以扩展或实现我自己的 Map,然后(比如如何Collections unmodifiableMap()
)覆盖所有可以更改键 throw 的方法UnsupportedOperationException
。但是在 Java 8 中,已经添加了大量使用 Lambda 函数的方法,这对于接口实现者来说是很好的,只要他们不能更改键即可。
AKA,我想避免这种冗长且容易出错的技术:
public final class FinalHashMap extends HashMap
{
@Override // anything that might be able to change the Map Keys
so_many_methods_and_edge_cases()
{ throws UnsupportedOperationException }
}
是否存在仅允许更改值的数据的接口Maps<>
?
我还有什么其他选择可以创建类似于 aMap<String,String>
的具有不可修改键但可修改值的东西?如果可能的话,我对良好的编码实践感兴趣。