将空白空间标记为数组而不使用null

时间:2011-12-13 22:25:14

标签: java null hashmap

我正在扩展AbstractMap,我想使用两个并行数组实现自己的哈希映射:

K[] keys;
V[] values;

假设我想要存储null值,我怎么能初始化这两个数组,以便我可以区分数组中我可以放置一些新的键值对的空间和我在哪里的空间我正在存储null

6 个答案:

答案 0 :(得分:2)

我可能建议不要使用两个数组,而是按照以下方式执行:

class Node {
    K key;
    V value;
}

Node[] nodes;

然后,非条目是nodes中等于null的元素。

答案 1 :(得分:0)

如果值可以为null但键不能为null,则使用null键意味着没有键。

如果键也可以为null,则可以使用并行的布尔数组来存储是否采用每个空格。

K[] keys;
V[] values;
boolean[] hasValue;

答案 2 :(得分:0)

不完全确定您的问题的详细信息,但您可以随时为您的“空白”设置一些特殊对象。

private static final Object BLANK = new Object();

然后,如果数组== BLANK中的项目,则将其视为空槽。

答案 3 :(得分:0)

由于只能有一个空键,因此您可以简单地使用一个特殊的引用值(不在数组中)来保存从此null键映射的对象的值(并且可能是一个布尔值,指示是否已设置此值) )。不幸的是,这可能会使迭代变得复杂。

E.g。

private boolean isNullMapped = false;
private V nullValue = null;

public put(K key, V value)
{
  if (key == null) { nullValue = value; }
  ...
}

或者,您可以将所有键包装在包装器对象中(假设您仍然希望使用并行数组而不是条目),并且如果此包装器对象中包含的值为null,则它表示null键。

E.g。

private static class KeyWrapper<K>
{
  public K key;
}

最后,作为一个值得考虑的问题,如果你的阵列中没有条目,而是直接持有K和V的数组,那么你如何考虑碰巧共享相同哈希码的不同密钥呢? java.util实现具有条目数组,这些条目也充当链接列表以解释这种可能性(顺便说一句,null键始终映射到数组索引0)。

答案 4 :(得分:0)

在您的方案中存储null 不是问题。只要keys[n] != null,只需返回values[n] values[n]是否null

请注意,我们不会要求您键入n,而是K类型的对象,因此Map的每次访问都需要搜索keys才能找到他们正在寻找的关键。

但是,如果您希望允许value存储null密钥,那么使用类似private static final Object NULL_KEY = "NULL"之类的内容可能就像其他建议所指出的那样。

private static final Object NULL_KEY = "NULL";
K[] keys;
V[] values;

private int find(K key) {
  for (int i = 0; i < keys.length; i++) {
    if (keys[i] == key) {
      return i;
    }
  }
  return -1;
}

public V put(K key, V value) {
  V old = null;
  if (key != null) {
    int i = find(key);
    if (i >= 0) {
      old = values[i];
      values[i] = value;
    } else {
      // ...
    }
  } else {
    return put((K) NULL_KEY, value);
  }
  return old;
}

public V get(K key) {
  if (key != null) {
    int i = find(key);
    if (i >= 0) {
      return values[i];
    }
    return null;
  } else {
    return (get((K) NULL_KEY));
  }
}

答案 5 :(得分:-1)

在java.util实现中,使用了一个表示null的特殊对象。