У меня есть ConcurrentHashMap
, который вызывается из разных потоков, чтобы поместить в него значения. Мне нужно вставить нулевые значения, но ConcurrentHashMap
не разрешает значения null
. Есть ли способ сделать это или альтернативный вариант сделать это в Java?Как добавить нулевые значения в ConcurrentHashMap
ответ
Один простой ответ: «Если значение равно null, не пытайтесь его добавить».
Другой ответ - взять страницу с .NET и ввести Nullable. Ваши значения будут экземпляром Nullable.
public class Nullable<T> {
private final T obj;
public Nullable(T t) {
obj = t;
}
public T get() {
return obj
}
}
Вы можете успешно сделать экземпляры Nullable с нулевым значением. Вы можете получить значение с помощью get().
--- Это старая версия ответа ---
Во-первых, почему бы вам нужно поставить пустой ключ? Это похоже на проблему в вашем дизайне.
При этом вы можете использовать объект stand-in для null. Скажем, ваш ключ - KeyLikeThing. Обычно KeyLikeThing имеет атрибуты, которые влияют на его хэш и равны свойствам. У вас может быть экземпляр KeyLikeThing в вашем мире нулевым. Когда ваш клиент хочет поместить нуль, он использует экземпляр KeyLikeThing.
public class KeyLikeThing {
public static final KeyLikeThing NULL = new KeyLikeThing();
// Other KeyLikeThing related stuff.
}
public class Storage<T> {
private ConcurrentHashMap m = new ConcurrentHashMap();
public T put(KeyLikeThing k, T val) {
KeyLikeThing kl = k == null ? KeyLikeThing.NULL : k;
return m.put(kl, val);
}
}
Я бы предложил использовать более четкое имя, чем 'NULL', в зависимости от вашего варианта использования. Например, вы можете использовать 'ANONYMOUS' для типа' Person'. – dimo414
Класс 'Nullable' не реализует' .equals() ', что означает, что операции, подобные' map.containsValue() ', будут нарушены. – dimo414
Ярмарка, но это демонстрационный класс. – Virmundi
Вместо того чтобы использовать null
, который не имеет смысловое значение и, как правило, считается antipattern, представитель «отсутствующий» понятие, как конкретный тип, который отражает ваши намерения и силы звонящим объяснить это правильно.
Общим решением является использование Optional
(для pre-Java 8 используйте Guava Optional
), чтобы представить отсутствие значения.
Таким образом, ваша карта будет иметь тип ConcurrentHashMap<Key, Optional<Value>>
.
Другим вариантом является представление, что вы собираетесь в виду, null
более непосредственно в типе вы храните на карте, например, если null
должно означать «это не используется существовать, но уже не» вы можете создать структуру классов, так как:
public abstract class Resource {
public abstract void doSomething();
public abstract ClosedResource close();
}
public class ActiveResource extends Resource {
public void doSomething() { ... }
public ClosedResource close() { ... }
}
public class ClosedResource extends Resource {
public void doSomething() { /* nothing to do */ }
public ClosedResource close() { return this; }
}
А потом просто есть ConcurrentHashMap<Key, Resource>
. Есть плюсы и минусы для обоих подходов в зависимости от ваших конкретных потребностей, но оба они объективно лучше, чем значения null
на вашей карте.
Вы также можете просто быть в состоянии избежать добавления null
сек на всех - если вы не можете создать четкую смысловую для null
, которая отличается от простого отсутствуя (как уже говорилось выше), просто использовать отсутствие в чтобы передать то, о чем вы заботитесь, вместо того, чтобы различать случаи отсутствия и присутствия, но - null
.
Зачем вам это нужно? Дайте нам прецедент. –
Возможно дублирование http://stackoverflow.com/questions/5699794/concurrenthashmap-alternative-with-null-key-capability – gastonmancini
Вместо этого вы можете использовать объект, который является вашим «нулем». –