Java 以元组为键的映射,remove/get 以元组为键
Java map with tuple as key, remove/get by tuple key
我有一个场景,我想要一个以元组作为键的排序映射:
var scheduledRunnables = new TreeMap<Tuple<Integer, String>, Runnable>(Comparator.comparing(Tuple::getKey));
添加时,我要添加一个元组:
scheduledRunnables.put(new Tuple<>(order, taskName), task);
排序时,我希望它按顺序整数排序,因为它决定了runnables的执行顺序。我不一定知道变量 taskName
的值。调用 get
时,我只想提供订单整数,原因与前面所述相同。调用 put
时,我想考虑整个对。所以像这样:
scheduledRunnables.put(new Tuple<>(1, "Some task"), () -> System.out.println("asdf"));
scheduledRunnables.get(1).run(); // Should output 'asdf'
scheduledRunnables.put(new Tuple<>(1, "Some task"), () -> System.out.println("qwerty"));
scheduledRunnables.get(1).run(); // Should output 'qwerty'
scheduledRunnables.remove(1).run(); // Should output 'qwerty' and remove from map
Tuple
class 只是一个看起来像这样的数据容器:
@Data
public class Tuple<K, V> {
private final K key;
private V value;
public Tuple(K key, V value) {
this.key = key;
this.value = value;
}
}
这将如何实施?如果不对 SortedMap 接口进行自定义实现,是否有可能?有没有更好的方法来实现我所追求的?
你可以让你value
不相关(它只是一个元信息)。所以它不需要初始化 class (可选参数)并且在使用 hashCode
或 equals
:
时不考虑
public class Tuple<K extends Comparable<K>, V> implements Comparable<Tuple<K, V>> {
private final K key;
private V value;
public Tuple(K key) {
this.key = key;
}
public Tuple(K key, V value) {
this.key = key;
this.value = value;
}
public int hashCode() {
return key.hashCode();
}
public boolean equals(Object obj) {
return obj == this || (obj instanceof Tuple) && key.equals(((Tuple) obj).key);
}
public int compareTo(Tuple<K, V> other) {
return key.compareTo(other.key);
}
}
我还使 Tuple
具有可比性,它只会比较键,因此您可以在没有自定义 Comparator
的情况下创建 TreeMap
,如下所示:
var scheduledRunnables = new TreeMap<Tuple<Integer, String>, Runnable>();
然后您可以通过以下方式调用您的 get:
Runnable runnable = scheduledRunnables.get(new Tuple<>(1));
When calling get
, I want to only supply the order integer
其中包含一些您的代码未强制执行的隐藏假设。如果您使用元组作为键,则仅通过该元组的一个 部分 从映射中获取一个条目就有可能 returning 多个条目。例如,考虑这个简化的代码:
Map<Tuple<Integer, String>, String> map = new TreeMap<>();
map.put(new Tuple<>(1, "Foo"), "First");
map.put(new Tuple<>(1, "Bar"), "Second");
? = map.get(1); // What should this return?
如果您只关心元组的一部分,那么 get()
预计会 return 多个 值。
如果您不关心元组的一部分,那么您不应该使用元组作为映射的键,因为键应该是不同的,但是 部分 键不是。不过,在不了解您的用例的情况下,我不确定什么是最适合您的选择。
老实说,只维护两张地图。
Map<Integer, Runnable> idToRunnable;
Map<Integer, String> idToName;
或者使用元组作为值而不是键:
Map<Integer, Tuple<String, Runnable>>
我有一个场景,我想要一个以元组作为键的排序映射:
var scheduledRunnables = new TreeMap<Tuple<Integer, String>, Runnable>(Comparator.comparing(Tuple::getKey));
添加时,我要添加一个元组:
scheduledRunnables.put(new Tuple<>(order, taskName), task);
排序时,我希望它按顺序整数排序,因为它决定了runnables的执行顺序。我不一定知道变量 taskName
的值。调用 get
时,我只想提供订单整数,原因与前面所述相同。调用 put
时,我想考虑整个对。所以像这样:
scheduledRunnables.put(new Tuple<>(1, "Some task"), () -> System.out.println("asdf"));
scheduledRunnables.get(1).run(); // Should output 'asdf'
scheduledRunnables.put(new Tuple<>(1, "Some task"), () -> System.out.println("qwerty"));
scheduledRunnables.get(1).run(); // Should output 'qwerty'
scheduledRunnables.remove(1).run(); // Should output 'qwerty' and remove from map
Tuple
class 只是一个看起来像这样的数据容器:
@Data
public class Tuple<K, V> {
private final K key;
private V value;
public Tuple(K key, V value) {
this.key = key;
this.value = value;
}
}
这将如何实施?如果不对 SortedMap 接口进行自定义实现,是否有可能?有没有更好的方法来实现我所追求的?
你可以让你value
不相关(它只是一个元信息)。所以它不需要初始化 class (可选参数)并且在使用 hashCode
或 equals
:
public class Tuple<K extends Comparable<K>, V> implements Comparable<Tuple<K, V>> {
private final K key;
private V value;
public Tuple(K key) {
this.key = key;
}
public Tuple(K key, V value) {
this.key = key;
this.value = value;
}
public int hashCode() {
return key.hashCode();
}
public boolean equals(Object obj) {
return obj == this || (obj instanceof Tuple) && key.equals(((Tuple) obj).key);
}
public int compareTo(Tuple<K, V> other) {
return key.compareTo(other.key);
}
}
我还使 Tuple
具有可比性,它只会比较键,因此您可以在没有自定义 Comparator
的情况下创建 TreeMap
,如下所示:
var scheduledRunnables = new TreeMap<Tuple<Integer, String>, Runnable>();
然后您可以通过以下方式调用您的 get:
Runnable runnable = scheduledRunnables.get(new Tuple<>(1));
When calling
get
, I want to only supply the order integer
其中包含一些您的代码未强制执行的隐藏假设。如果您使用元组作为键,则仅通过该元组的一个 部分 从映射中获取一个条目就有可能 returning 多个条目。例如,考虑这个简化的代码:
Map<Tuple<Integer, String>, String> map = new TreeMap<>();
map.put(new Tuple<>(1, "Foo"), "First");
map.put(new Tuple<>(1, "Bar"), "Second");
? = map.get(1); // What should this return?
如果您只关心元组的一部分,那么 get()
预计会 return 多个 值。
如果您不关心元组的一部分,那么您不应该使用元组作为映射的键,因为键应该是不同的,但是 部分 键不是。不过,在不了解您的用例的情况下,我不确定什么是最适合您的选择。
老实说,只维护两张地图。
Map<Integer, Runnable> idToRunnable;
Map<Integer, String> idToName;
或者使用元组作为值而不是键:
Map<Integer, Tuple<String, Runnable>>