【问题标题】:How to fix size of LinkedHashSet?如何修复 LinkedHashSet 的大小?
【发布时间】:2018-03-08 10:38:56
【问题描述】:

我需要一个固定大小为 n 的 LinkedHashSet ,这样当我们插入第 n+1 个元素时,第一个元素会被自动删除并在末尾插入新元素。

LinkedHashSet <Integer> = new LinkedHashSet <Integer> () ;

我应该如何实现构造函数来固定大小?

【问题讨论】:

  • 您必须创建 LinkedHashSet 的子类并自己实现该逻辑。
  • 没有实现,你需要实现 LinkedHashSet 并覆盖一些方法,如“add”
  • @Eran 我只是一个初学者。请帮忙。
  • 在构造函数中,只取一个 maxLength 字段的值;它是HashSet.add,您需要重写以实现您的逻辑(例如,调用 super.add,然后如果 size() > maxLength 删除第一个元素)
  • LinkedHashSet 有具体原因吗?遵循 Aaron 的建议并不难,但请注意 LinkedHashSet 处理添加已存在元素的方式(剧透:插入顺序更新)。我不知道在这种情况下你想发生什么,但我的印象是,将LinkedList 或其他一些Queue 实现作为基类会做得更好。

标签: java hash set


【解决方案1】:

默认情况下,LinkedHashSet 无法做到这一点。你可以在这里阅读原因:https://stackoverflow.com/a/7632240/9337345

您唯一能做的就是创建一个继承的 LinkedHashSet,它负责根据您的需要固定大小。

例如:

import java.util.Iterator;
import java.util.LinkedHashSet;

public class MyLinkedHashSet<T> extends LinkedHashSet<T> {
    private long maxSize;

    public MyLinkedHashSet(long maxSize) {
        this.maxSize = maxSize;
    }

    @Override
    public boolean add(T item) {
        if(size() == maxSize) {
            removeFirst();
        }
        return super.add(item);
    }

    private void removeFirst() {
        if(size() > 0) {
            Iterator<T> iterator = iterator();
            T item = iterator.next();
            remove(item);
        }
    }

    public static void main(String[] args) {
        LinkedHashSet<Integer> set = new MyLinkedHashSet<>(3);
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        System.out.println(set);    // [2, 3, 4]
        set.clear();
        System.out.println(set);    // []
        set.addAll(Arrays.asList(1, 2, 3, 4, 5));
        System.out.println(set);    // [3, 4, 5]
    }
}

我希望这就是你的意思。

【讨论】:

  • 非常感谢。乔巴。这就是我一直在寻找的。​​span>
【解决方案2】:

要在 java 中实现一个固定大小的 LinkedHashSet,我们将执行以下操作:

  1. 根据[LinkedHashSet](new LinkedHashMap(16, .75f))的来源,它基于一个LinkedHashMap的实现
  2. 查看LinkedHashMap的文档后,我们看到它有一个名为[removeEldestEntry](https://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html#removeEldestEntry(java.util.Map.Entry))的方法,我们可以将其用于自动删除的目的

最终,我们将得到以下实现:

Set<Integer> unnamedVariable = Collections.newSetFromMap(new LinkedHashMap<Integer, Boolean>() {

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Boolean> eldest) {
        return this.size() > n;
    }

});

与使用迭代器手动删除最后一个条目相比,这为我们提供了一个高性能的解决方案,因为我们重用了后端层的现有功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多