Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否有任何数据结构可以避免重复、保持顺序和随机访问_Java_Python_Collections - Fatal编程技术网

Java 是否有任何数据结构可以避免重复、保持顺序和随机访问

Java 是否有任何数据结构可以避免重复、保持顺序和随机访问,java,python,collections,Java,Python,Collections,之前,我正在寻找具有以下特征的数据结构 避免重复 迭代顺序将与插入顺序相同 在Java中,我使用,在Python中,我使用 现在,在2个要求的顶部,我想有一个额外的要求 能够通过索引进行随机访问,意味着我可以通过数据[123] 是否有可用的数据结构?或者我需要退回使用列表列表能够完全满足第二和第三项要求,但不能满足第一项要求。我可能需要在插入过程中执行手动(和慢速检查)以避免重复?java.util.Set不提供get()和Set()等随机访问方法,因此它的大多数/所有实现也不提供。您可

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

  • 避免重复
  • 迭代顺序将与插入顺序相同
在Java中,我使用,在Python中,我使用

现在,在2个要求的顶部,我想有一个额外的要求

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

是否有可用的数据结构?或者我需要退回使用
列表
<代码>列表能够完全满足第二和第三项要求,但不能满足第一项要求。我可能需要在插入过程中执行手动(和慢速检查)以避免重复?

java.util.Set不提供get()和Set()等随机访问方法,因此它的大多数/所有实现也不提供。您可以创建自己的
Set
实现来提供此功能,也许可以使用一个ArrayList来保存数据。

java.util.Set
不提供get()和Set()等随机访问方法,因此它的大多数/所有实现也不提供。您可以创建自己的
Set
实现,该实现将提供此功能,可能带有用于保存数据的ArrayList。

LinkedHashSet类提供toArray方法,该方法应适合您的需要。

LinkedHashSet类提供toArray方法,这应该适合您的需要。

Java中的一个简单方法是创建一个包装类,该类实现了
集合
列表
接口,并且包含
哈希集
数组列表
。更新操作将需要更新两个内部集合,而读取操作将映射到提供正确语义和最佳性能的内部集合。唯一稍微棘手的方法是
iterator()
,您需要安排
remove
更新这两个集合

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

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

跟进

我还没有找到一个通用的实现类来实现
Set
List
接口。我认为,原因是当您组合接口时,存在语义异常。例如,(正如@ColinD所指出的)如果使用列表中已经存在的元素调用
E set(int,E)
,则不清楚结果应该是什么。以一种让每个人都满意的方式来处理这个问题可能是不可能的,我可以理解为什么他们可能决定不去柏油坑游泳

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

  • 选择适合您的应用程序的语义
  • 将应用程序编码为完全不使用该方法,或者
  • 为应用程序编写代码以避免被异常所困扰
(例如,您可以将其编码为忽略
set
方法的结果,如果存在重复,则抛出未检查的异常,或者如果存在重复,则返回
null
或某个可分辨对象。)


作为记录,自定义集合类违反接口约定并不是不可原谅的。事实上,甚至Java设计人员也会这样做——请参见IdentityHashMap。不可原谅的是,没有在javadocs中记录违反合同的行为。

Java中的一个简单方法是创建一个包装类,该类实现
列表
接口,并包含
哈希集
数组列表
。更新操作将需要更新两个内部集合,而读取操作将映射到提供正确语义和最佳性能的内部集合。唯一稍微棘手的方法是
iterator()
,您需要安排
remove
更新这两个集合

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

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

跟进

我还没有找到一个通用的实现类来实现
Set
List
接口。我认为,原因是当您组合接口时,存在语义异常。例如,(正如@ColinD所指出的)如果使用列表中已经存在的元素调用
E set(int,E)
,则不清楚结果应该是什么。以一种让每个人都满意的方式来处理这个问题可能是不可能的,我可以理解为什么他们可能决定不去柏油坑游泳

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

  • 选择适合您的应用程序的语义
  • 将应用程序编码为完全不使用该方法,或者
  • 为应用程序编写代码以避免被异常所困扰
(F)
class IndexableUniqueList(object):
    """
    >>> a = IndexableUniqueList()
    >>> a['x'] = 1
    >>> a['x']
    1
    >>> a['y'] = 2
    >>> a['y']
    2
    >>> a.get_key_by_index(0)
    'x'
    >>> a.get_value_by_index(0)
    1
    >>> a.get_key_by_index(1)
    'y'
    >>> a.get_value_by_index(1)
    2
    >>> a['x'] = 3
    >>> a.get_key_by_index(0)
    'x'
    >>> a.get_value_by_index(0)
    3
    >>> a.set_value_by_index(0, 4)
    >>> a['x']
    4
    >>> [val for val in a]
    ['x', 'y']
    """
    def __init__(self):
        self.items_by_index = []
        self.items_by_key = {}

    def __getitem__(self, key):
        return self.items_by_key[key][1]

    def __setitem__(self, key, value):
        if key in self.items_by_key:
            idx, old_value = self.items_by_key[key]
            self.items_by_key[key] = (idx, value)
            self.items_by_index[idx] = (key, value)
            return

        idx = len(self.items_by_index)
        self.items_by_key[key] = (idx, value)
        self.items_by_index.append((key, value))
    def get_key_by_index(self, idx):
        return self.items_by_index[idx][0]
    def get_value_by_index(self, idx):
        key = self.get_key_by_index(idx)
        return self.items_by_key[key][1]
    def set_value_by_index(self, idx, value):
        key = self.items_by_index[idx][0]
        self[key] = value
    def __iter__(self):
        for key, value in self.items_by_index:
            yield key