以元组为键的Java映射,通过元组键进行删除/获取

时间:2019-02-20 13:34:17

标签: java treemap

我有一种情况,我希望有一个以元组为键的排序映射:

var scheduledRunnables = new TreeMap<Tuple<Integer, String>, Runnable>(Comparator.comparing(Tuple::getKey));

添加时,我要添加一个元组:

scheduledRunnables.put(new Tuple<>(order, taskName), task);

排序时,我希望按整数排序,因为它确定了可运行对象的执行顺序。我不一定知道变量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类只是一个数据持有人,看起来像这样:

@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接口进行自定义实现,是否可以实现?有没有更好的方法来实现我的追求?

3 个答案:

答案 0 :(得分:4)

老实说,只需维护两张地图。

deltaTime = datetime.datetime(2015,3,21,14) - datetime.datetime(2015,1,1)
resampled_df = df.resample('Y', loffset=deltaTime).mean()

或者使用元组作为值而不是键:

Map<Integer, Runnable> idToRunnable;
Map<Integer, String> idToName;

答案 1 :(得分:3)

您可以使您value不相关(它只是元信息)。因此,它不需要初始化类(可选参数),并且在使用hashCodeequals时无需考虑:

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具有可比性,它将只比较密钥,因此您可以创建TreeMap而无需这样的自定义Comparator

var scheduledRunnables = new TreeMap<Tuple<Integer, String>, Runnable>();

然后您可以致电:

Runnable runnable = scheduledRunnables.get(new Tuple<>(1));

答案 2 :(得分:1)

  

调用get时,我只想提供订单整数

其中有一些隐藏的假设,您的代码没有执行这些假设。如果您使用元组作为键,那么只需从该元组的 part 中取出一个条目即可返回多个条目。通过示例,请考虑以下简化代码:

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()应该会返回多个值。

如果您不关心元组的一部分,则不应将元组用作地图的键,因为键应该是不同的,而键的 parts 却不是。但是,在不了解您的用例的情况下,我不确定哪个是您的最佳选择。