LinkedHashSet - 广告订单和重复项 - 保持最新的“在顶部”

2022-09-01 07:28:43

我需要一个能够保持广告订单并具有唯一值的产品系列。LinkedHashSet看起来像是要走的路,但有一个问题 - 当两个项目相等时,它会删除最新的项目(这是有道理的),这里有一个例子:

set.add("one");
set.add("two");
set.add("three");
set.add("two");

将打印:LinkedHashSet

one, ,twothree

但我需要的是:

这里最好的解决方案是什么?是否有任何集合/集合方法可以执行此操作,或者我应该手动实现它?


答案 1

大多数Java集合都可以扩展以进行调整。

子类 LinkedHashSet,重写 add 方法。

class TweakedHashSet<T> extends LinkedHashSet<T> {

    @Override
    public boolean add(T e) {
        // Get rid of old one.
        boolean wasThere = remove(e);
        // Add it.
        super.add(e);
        // Contract is "true if this set did not already contain the specified element"
        return !wasThere;
    }

}

答案 2

您只需使用以下特殊功能:LinkedHashMap

Set<String> set = Collections.newSetFromMap(new LinkedHashMap<>(16, 0.75f, true));
set.add("one");
set.add("two");
set.add("three");
set.add("two");
System.out.println(set); // prints [one, three, two]

在Oracle的JRE中,无论如何都是由a支持的,因此没有太多的功能差异,但是这里使用的特殊构造函数将配置为更改每次访问的顺序,而不仅仅是在插入时。这可能听起来太多了,但实际上只影响已经包含的键(意义上的值)的插入。其他受影响的操作(即 )不被返回的 使用。LinkedHashSetLinkedHashMapLinkedHashMapSetMapgetSet

如果你没有使用Java 8,由于有限的类型推断,你必须对编译器有所帮助:

Set<String> set
    = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>(16, 0.75f, true));

但功能是相同的。