很不幸,Java中的默认设置并没有设计提供“获取”操作,正如jschreiner所准确解释的。
使用迭代器查找感兴趣的元素(由dacwe建议)或删除元素并重新添加其更新后的值(由KyleM建议)的解决方案可能有效,但可能非常低效。
重写equals的实现使得不相等的对象“相等”,正如David Ogren正确指出的那样,可能会轻易引起维护问题。
而使用Map作为明确的替代方案(正如许多人建议的那样),在我看来,会使代码变得不够优雅。
如果目标是获取包含在集合中的元素的原始实例(希望我正确理解了您的用例),这里有另一种可能的解决方案。
在使用Java开发客户端服务器视频游戏时,我个人遇到了与您相同的需求。在我的情况下,每个客户端都存储了服务器上组件的副本,问题是当客户端需要修改服务器上的对象时。
通过互联网传递对象意味着客户端无论如何都有不同的该对象实例。为了将此“复制”的实例与原始实例匹配,我决定使用Java UUIDs。
因此,我创建了一个抽象类UniqueItem,自动为其子类的每个实例提供随机唯一ID。
此UUID在客户端和服务器实例之间共享,因此可以通过简单地使用Map进行匹配。
但是,在类似用例中直接使用Map仍然不够优雅。有人可能会认为使用Map可能更加复杂,难以维护和处理。
出于这些原因,我实现了一个名为MagicSet的库,使开发人员可以“透明”地使用Map。
https://github.com/ricpacca/magicset
像原始的Java HashSet一样,MagicHashSet(是库中提供的MagicSet实现之一)使用支持HashMap,但不同于将元素作为键和虚拟值作为值,而是使用元素的UUID作为键和元素本身作为值。与普通HashSet相比,这不会导致内存使用方面的开销。
此外,可以像Set一样完全使用MagicSet,但还提供了一些额外的方法,如getFromId(),popFromId(),removeFromId()等,提供了其他功能。
唯一要求使用它的是,您想要存储在MagicSet中的任何元素都需要扩展抽象类UniqueItem。
这里有一个代码示例,假设从一个MagicSet中检索具有相同UUID(甚至只有UUID)的另一个城市实例,以获取该城市的原始实例。
class City extends UniqueItem {
public void doSomething() {
}
}
public class GameMap {
private MagicSet<City> cities;
public GameMap(Collection<City> cities) {
cities = new MagicHashSet<>(cities);
}
public void doSomethingInCity(UUID cityId) {
City city = cities.getFromId(cityId);
city.doSomething();
}
}
SortedSet
及其实现,它们是基于映射的(例如,TreeSet
允许访问first()
)。 - Eliran MalkaNSSet
)有这样一个方法,称为member
,它返回集合中与member
方法参数“相等”的对象(可能是不同的对象,也可能具有不同的属性,但相等性检查不会考虑这些差异)。 - Mecki