Java - 如何通过密钥获取存储在HashMap中的密钥对象(或条目)?

时间:2017-11-24 23:41:37

标签: java dictionary key

我想获得"规范"用于查询地图的每个键的关键对象。见这里:

 module.exports = function(config) {
  config.set({

// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',


// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],


// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-resource/angular-resource.js',
  'app/**/*.js',
  'test/**/*.js'
],


// list of files to exclude
exclude: [
],


// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},


// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],


// web server port
port: 9876,


// enable / disable colors in the output (reporters and logs)
colors: true,


// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,


// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,


// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],


// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
 })
 }

Map<UUID, String> map = new HashMap(); UUID a = new UUID("ABC..."); map.put(a, "Tu nejde o zamykání."); UUID b = new UUID("ABC..."); String string = map.get(b); // This gives that string. // This is what I am looking for: UUID againA = map.getEntry(b).key(); boolean thisIsTrue = a == againA; 使用HashMap,这对于多个唯一对象是相同的。所以我想从地图中获取实际的密钥,无论用什么对象查询地图,它都将始终相同。

有没有办法从地图中获取实际的密钥对象?我在界面中看不到任何东西,但也许我忽略了一些聪明的伎俩?

(迭代所有条目或键不算数。)

4 个答案:

答案 0 :(得分:2)

  

有没有办法从地图中获取实际的密钥对象?

好的,所以我将对你的意思做出一些假设。毕竟,你说你的问题不需要澄清,所以我可以看到的明显含义必须是正确的。对? : - )功能

答案是否定的。没有办法。

示例场景(不可编译!)

UUID uuid = UUID.fromString("xxxx-yyy-zzz");
UUID uuid2 = UUID.fromString("xxxx-yyy-zzz");  // same string
println(uuid == uuid2);  // prints false
println(uuid.equals(true));  // prints true

Map<UUID, String> map = new ...
map.put(uuid, "fred");
println(map.get(uuid)); // prints fred
println(map.get(uuid2)); // prints fred (because uuid.equals(uuid2) is true)

...但是,Map API没有提供在{{1}中找到实际键(在上面的示例中为uuid)的方法除了迭代键或入口集之外。而且我不知道任何现有的map类(标准或第三方)确实提供了这个 1

但是,您可以实现您自己的Map类,并使用其他方法返回实际的密钥对象。虽然你有更多的代码可以编写,测试,维护等等,但是没有技术的原因你不能这样做。

但我想补充一点,我同意吉姆加里森。如果你有一个场景,你有UUID对象(具有按值相等的语义),并且你也想通过身份语义实现相等,那么你的应用程序的设计可能有问题。正确的方法是将Map实现更改为始终为同一输入字符串返回相同的UUID.fromString(...)对象。

1 - 这并不是说这样的地图实现不存在。但是,如果确实如此,应该能够找到它,如果你看起来足够努力注意,要求我们找到或推荐一个库的问题是偏离主题的!

答案 1 :(得分:1)

有一种(相对)简单的方法。我在我的应用程序中不时地在需要时这样做...不是为了==测试的目的,而是为了减少存在数万个对象时存储的相同对象的数量,并且相互交叉引用。这大大减少了我的内存使用量,并提高了性能......同时仍然使用equals()进行相等性测试。

只需维护一个用于实习键的平行地图。

Map<UUID, UUID> interned_keys = ...

UUID key = ...
if (interned_keys.contains(key))
    key = interned_keys.get(key)

当然,当存储的对象知道它自己的身份是什么时,它会好得多。然后你基本上免费获得实习。

class Item {
    UUID key;
    // ...
}

Map<UUID, Item> map = ...
map.put(item.key, item);

UUID key = ...
key = map.get(key).key;  // get interned key

答案 2 :(得分:0)

我认为有充分的理由想要真正的钥匙。例如,以节省内存。还请记住,实际密钥可能会存储其他对象。例如,假设您有一个图形的顶点。顶点可以存储实际数据(例如,说一个字符串)以及入射顶点。顶点哈希值只能取决于数据。因此,要查找包含一些数据的顶点, D,查找具有数据D且无入射值的顶点。现在,如果您可以在地图中返回实际的顶点,那么您将能够获取到顶点的实际事件。

在我看来,许多地图实现都可以轻松提供getEntry方法。例如,get的HashMap实现是:

  public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
  }

  final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
 }

可以使用getNode方法返回一个Entry:

 public getEntry(Object key){
   Node<K,V> e = getNode(hash(key),key);
   if(e == null) return null;
   return new Entry<>(e.key,e.value);
 }

答案 3 :(得分:-1)

它可以提供帮助。您可以在下面使用a。

Map<String,Object> map = new HashMap<>();
        map.put("hello1", new String("Hello"));
        map.put("hello2", new String("World"));
        map.put("hello3", new String("How"));
        map.put("hello4", new String("Are u"));

        for(Map.Entry<String,Object> e: map.entrySet()){
             System.out.println(e.getKey());
        }