gpt4 book ai didi

java - 如何维护多个集合,其中一个对象只能存在于一个集合中?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:24:28 25 4
gpt4 key购买 nike

我有一个类和一个枚举,看起来像这样

class Container{
static int next_id = 0;
final int id = next_id++;
State state = State.one;
}

enum State{
one, two, three, four, five;
}

我想维护 Container 的多个集合,但维护 Container 的任何实例,它只存在于一个集合中。集合需要线程安全,我不能将容器直接存储在基于散列的集合中,因为它的散列会根据其当前状态发生变化。

--编辑--

为了进一步阐明,这样做的目标是能够检索处于给定状态的所有容器,而不必检查每个容器的状态,因为有数千个容器。

最佳答案

如果不自己编写一些代码,您将无法确保这一点,因为要保持一致性,即容器根据其状态恰好属于一个集合,不仅需要集合的支持,还需要成员的支持。

不管目标语言是java,我可能会建议链表,像这样:

class Container{
static int next_id = 0;
final int id = next_id++;
final Node<Container> node;
State state;

public Container() {
node = new Node<>(this);
setState(State.one);
}

public void setState(State state) {
if(this.state != null) node.unlink();
this.state = state;
if(this.state != null) this.state.containers.add(node);
}
}

enum State{
one, two, three, four, five;
final List<Container> containers = ...;
}

此代码之所以有效,是因为知道节点后,可以在 O(1) 中取消元素与链表的链接。 (add 当然也是 O(1))。 Java默认链表不暴露节点,每次访问都需要线性查找,效率低下。

鉴于此,下一个最好的办法是使用基于哈希的方法。一些代码仍然可以保留:

  • 设置状态有点复杂,所以逻辑应该放在setter中,而不是在客户端做container.state = ...
  • 只要容器集合是应用程序范围的(提示:在托管环境中,例如应用程序服务器,它们几乎不是!),它们可以直接由枚举维护。否则,给容器一些 Context持有 EnumMap<State, Map<Integer, Container>>或类似的。

结果:

class Container{
static int next_id = 0;
final int id = next_id++;
State state;

public Container() {
setState(State.one);
}

public void setState(State state) {
if(this.state != null) this.state.containers.remove(id);
this.state = state;
if(this.state != null) this.state.containers.put(id, node);
}
}

enum State{
one, two, three, four, five;
final Map<Integer, Container> containers = new HashMap<>();
}

使用id作为key,就不用担心自己的hashCode了和 equals实现。


关于可见性:您真的、真的想至少将这些设为私有(private)或默认(我正在查看 State 中的 map )。

关于线程安全:我不想在这里探出头来(我不是专家),而是使用 ConcurrentHashMap s 可能会做很多你需要的事情。另外,同步 setState .如果不这样做,两个并发更新可能会将容器插入到两个映射中。最后,final int id = next_id++;据我所知不是线程安全的,因为++不是原子的。你可以使用 AtomicInteger在这里。

关于java - 如何维护多个集合,其中一个对象只能存在于一个集合中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23811098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com