是否有任何数据结构可以避免重复,保留顺序和随机访问 - java

以前,我正在寻找具有以下特征的数据结构。

避免重复
迭代顺序将与插入顺序相同

在Java中,我使用LinkHashSet,在Python中,我使用OrderedDict

现在,除了2个要求之外,我还有一个附加要求

能够通过索引进行随机访问,这意味着我可以通过data[123]访问

有没有可用的数据结构?还是我需要退回使用ListList可以完全满足第二和第三要求,但不能满足第一要求。为避免重复,我可能需要在插入过程中执行手动操作(并进行缓慢检查)?

参考方案

Java中的一种简单方法是创建一个包装类,该类同时实现SetList接口,并且同时包含HashSetArrayList。更新操作将需要更新两个内部集合,并且读取操作将映射到任何提供正确语义和最佳性能的内部集合。唯一有点棘手的方法是iterator(),您需要安排remove更新两个集合。

这种方法将为您的读取操作提供“两全其美”的性能,但更新速度一定较慢。特别是,在给定位置插入并删除将是O(N)操作。

(我注意到LinkedHashSet不是直接解决方案,因为它不提供get(int)方法。您可以通过LinkedHashSet迭代器实现此方法,从而使其成为O(N)操作。可能不是您想要的。)

跟进

我找不到能够同时实现SetList接口的通用实现类。我认为原因是当组合接口时存在语义异常。例如,(如@ColinD所指出的)如果使用已在列表中的元素调用E set(int, E),则不清楚结果应该是什么。以一种令所有人满意的方式来处理这个问题可能是不可能的,而且我可以理解为什么他们可能决定不去沥青场游泳。

但是,如果您为应用程序的内部使用创建Set + List类,那么我认为这不是主要问题。你要么

选择适合您的应用程序的语义,
对您的应用程序进行编码,使其根本不使用该方法,或者
对应用程序进行编码,以免被异常咬住。

(例如,您可以对其进行编码,以忽略set方法的结果,如果存在重复项则抛出未经检查的异常,或者如果存在重复项则返回null或某些可区分对象。)

作为记录,自定义集合类违反接口协定并非不可原谅。确实,即使Java设计人员也可以做到这一点-请参阅IdentityHashMap。不可原谅的是没有在javadocs中记录合同违规。

Java:找到特定字符并获取子字符串 - java

我有一个字符串4.9.14_05_29_16_21,我只需要获取4.9。数字各不相同,所以我不能简单地获得此char数组的前三个元素。我必须找到最正确的.并将其子字符串化直到那里。我来自Python,因此我将展示Python的实现方法。def foobar(some_string): location = some_string.rfind('.&…

Java-固定大小的列表与指定初始容量的列表之间的差异 - java

我在理解这一点上遇到了问题。当我们做 List<Integer> list = Arrays.asList(array); 我们不能在该列表上使用添加,删除之类的方法。我知道Arrays.asList()返回固定大小的列表。我不明白的是,如果我们创建一个具有指定初始容量的列表,例如List<Integer> list2 = new A…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…