我想知道是否有任何Java数据结构或库可以让我在没有重复键的情况下拥有多个键?
在我的用例中,我有两种不同类型的密钥:个人识别码和驾照。我想使用这两个键中的任何一个来查找一个值(本例中是他们的汽车)。当我试图添加一个重复的键( pin-1 )时,应该会出现错误,因为pin-1已经被分配了。
structure.add("pin-1", "driverLicense-1", Car.TOYOTA);
structure.add("pin-2", "driverLicense-2", Car.FORD);
structure.add("pin-1", "driverLicense-3", CAR.FORD); // invalid because pin-1 is already assigned我遇到的唯一这样做的库是谷歌的Guava及其实现Table的HashBasedTable类。我对这个库的问题是它不能防止重复的键。
Table<String, String, Car> table = HashBasedTable.create();
table.put("pin-1", "driverLicense-1", Car.TOYOTA);
table.put("pin-2", "driverLicense-2", Car.FORD);
table.put("pin-1", "driverLicense-3", Car.FORD); // is valid发布于 2021-11-06 00:55:24
我会使用两个Map,封装在一个类中,一起处理它们的更新,例如:
class CarOwnership {
private final Map<String,Car> byPin = new HashMap<>();
private final Map<String,Car> byLicense = new HashMap<>();
public void put(String pin, String licence, Car car) {
if (byPin.containsKey(pin)) {
throw new RuntimeException("duplicate pin " + pin);
}
if (byLicense.containsKey(licence)) {
throw new RuntimeException("duplicate licence " + license);
}
byPin.put(pin, car);
byLicense.put(licence, car);
}
public Car findByPin(String pin) {
return byPin.get(pin);
}
...
}在您正在使用的实际数据结构周围使用容器的好处是,它允许您将错误处理放在一个位置,并为您提供执行验证的地方。
这与HashBasedTable有所不同,后者是一种Map of Map,因此需要两个密钥组件才能达到值。
发布于 2021-11-06 07:06:51
据我所知,这可以通过在映射中为每个传递的键创建一个条目来实现。因此,只有一个映射,但是每次调用put()都可能添加多个条目(每个键对应一个条目)。不确定Java中是否有内置的API来实现这一点,但这里有一个简单的实现。
public class MultikeyMap<K, V>{
/* Holds all the values. */
private Map<K, V> map = new HashMap<>();
/** Creates one entry in this.map for each key passed here. */
public void put( V value, K... keys ) {
if( keys == null || keys.length == 0 ) throw new NullPointerException();
/* For every key, create an entry. */
for( K key : keys ) map.putIfAbsent( key, value );
}
public V get( K key ) {
if( key == null ) throw new NullPointerException();
return map.get( key );
}
@Override
public String toString(){
return this.map.toString();
}
public static void main( String[] args ){
MultikeyMap<String, Car> m = new MultikeyMap<>();
m.put( Car.HONDA, "pin-1", "dl-1" );
System.out.println( m );
m.put( Car.TATA, "pin-2", "dl-2" );
System.out.println( m );
m.put( Car.TOYOTA, "pin-1", "dl-3" );
System.out.println( m );
}
private static enum Car{
TOYOTA, HONDA, MARUTI, TATA;
}
}以下是运行main()的输出。
{pin-1=HONDA, dl-1=HONDA}
{pin-2=TATA, pin-1=HONDA, dl-2=TATA, dl-1=HONDA}
{pin-2=TATA, dl-3=TOYOTA, pin-1=HONDA, dl-2=TATA, dl-1=HONDA}关于这个设计的一些要点:
当遇到现有的键时,它不会抛出异常,只是忽略它。
Map<Object, Car>.https://stackoverflow.com/questions/69860616
复制相似问题