当前位置: 首页 > 面试题库 >

Java中的排序数组列表

宰父远
2023-03-14
问题内容

我为无法快速找到答案感到困惑。我本质上是在寻找Java中的一种实现java.util.List接口的数据结构,但该结构按顺序存储其成员。我知道您可以使用法线ArrayListCollections.sort()在其上使用,但是我遇到的情况是,我偶尔会添加并经常从列表中检索成员,并且我不想每次检索成员时都对其进行排序,以防万一新增加了一个。谁能指出我在JDK甚至第3方库中都存在的这种东西?

编辑 :数据结构将需要保留重复项。

总结
:我发现所有这些都很有趣,并且学到了很多东西。尤其值得一提的是Aioobe,因为他在实现上述要求方面的毅力(主要是支持重复项的有序java.util.List实现)。我接受了他的回答,这对我的要求是最准确的,并且即使我提出的要求不完全是我所寻求的含义,也最能引起我的思考。

我要求的问题在于List接口本身以及接口中可选方法的概念。引用javadoc:

该界面的用户可以精确控制列表中每个元素的插入位置。

插入排序列表并不能精确控制插入点。然后,您必须考虑如何处理某些方法。就拿add例如:

public boolean add(Object o)

 Appends the specified element to the end of this list (optional

operation).

现在,您处于以下两种情况中的一种令人不舒服的情况:1)打破合同并实现add的排序版本2)让add元素添加到列表的末尾,破坏排序的顺序3
add)通过抛出来抛弃(作为其可选项)一UnsupportedOperationException和实施这增加了在一个有序的物品的另一种方法。

选项3可能是最好的,但是我发现它不适合使用具有不能使用的add方法和不在接口中的另一个sortedAdd方法。

其他相关解决方案(无特定顺序):

  • java.util.PriorityQueue,它可能比我所需要的更接近我的需求。在我的案例中,队列不是对象集合的最精确定义,但是在功能上,它可以完成我需要做的所有事情。
  • net.sourceforge.nite.util.SortedList。但是,此实现通过实现add(Object obj)方法中的排序打破了List接口的协定,并且奇怪的是没有的方法add(int index, Object obj)。总体共识表明,throw new UnsupportedOperationException()在这种情况下可能是更好的选择。
  • Guava的TreeMultiSet一个支持重复项的set实现
  • ca.odell.glazedlists.SortedList 此类在Javadoc中附带警告:Warning: This class breaks the contract required by List

问题答案:

简约解决方案

这是一个“最小”的解决方案。

class SortedArrayList<T> extends ArrayList<T> {

    @SuppressWarnings("unchecked")
    public void insertSorted(T value) {
        add(value);
        Comparable<T> cmp = (Comparable<T>) value;
        for (int i = size()-1; i > 0 && cmp.compareTo(get(i-1)) < 0; i--)
            Collections.swap(this, i, i-1);
    }
}

插入以线性时间运行,但是无论如何,这将是您使用ArrayList获得的结果(插入元素右侧的所有元素都必须以一种或另一种方式移动)。

插入一些不可比较的结果会导致ClassCastException。(这也是采用的方法PriorityQueue
依赖自然顺序的优先级队列也不允许插入不可比较的对象(这样做可能会导致ClassCastException)。

覆写 List.add

请注意,以排序的方式覆盖List.add(或List.addAll为此)插入元素将
直接违反接口规范 。您 可以 做的是重写此方法以引发UnsupportedOperationException

来自的文档List.add

boolean add(E e)
将指定的元素追加到此列表的末尾(可选操作)。

同样的道理也适用于这两个版本add,两个版本的addAllset。(根据列表界面,所有这些都是可选操作。)

一些测试

SortedArrayList<String> test = new SortedArrayList<String>();

test.insertSorted("ddd");    System.out.println(test);
test.insertSorted("aaa");    System.out.println(test);
test.insertSorted("ccc");    System.out.println(test);
test.insertSorted("bbb");    System.out.println(test);
test.insertSorted("eee");    System.out.println(test);

....打印:

[ddd]
[aaa, ddd]
[aaa, ccc, ddd]
[aaa, bbb, ccc, ddd]
[aaa, bbb, ccc, ddd, eee]


 类似资料:
  • 我有一个点列表,每个点都是一个大小为2的小列表。我想按x的递增顺序对点列表进行排序,如果x值相等,我就按y的递减顺序排序来打破平局。 我编写了一个自定义比较器来对点进行排序,如下所示: 以下是排序前的输入: 以下是使用上述比较器排序后产生的结果: 观察:- 输入按x的升序排序。 (5,12)被正确地放在(5,10)之前 (9,-15)被正确地放在(9,-1000)之前 然而,(10001,-10)

  • 问题内容: 我有以下课程。在此,虹膜是具有某些属性的另一类。 我想对此数组列表进行排序(即列表 helperList),基于距离参数降序。我已经编写了以下方法,但是它不起作用。 有人可以提出解决方案吗? 问题答案: 为什么不让您的类实现接口,然后使用Collections类提供的内置排序方法。 我认为这可以解决问题。另外,此方法是稳定的。 http://docs.oracle.com/javase

  • 问题内容: 给定不同整数的数组,打印数组的所有排列。 例如: 问题答案: 我们可以借助递归来解决问题。递归很难解释,所以我创建了一个递归树来演示它。 这是相同的代码。 当你运行上面的程序时,你会得到以下输出: 我已经用下图说明了递归是如何在这里工作的。 您需要在新窗口中打开此图表并对其进行缩放。 由于数组中有 3 个元素,因此每个节点有 3 个分支。

  • 我是Java和Stack Overflow的新手,我有一个关于排列的问题。 方法:我使用中的对象生成。每个的大小从(可能最小为1)到,并包含具有唯一名称属性的自定义生成对象。 问题:现在我的问题是如何在我的外部(y轴)中获得从第一个到最后一个的所有可能对象组合的排列(我想我们可以说这是x轴)? 我试着举一个简单的例子: : 1.1|1.2|1.3 : 2.1 : 3.1|3.2 这里,这些位于外部

  • 我试图建立一个方法,将排序一个二维数组的双打按列。基于所提供的规范,此方法也不应该采用长度不等的行的粗糙数组。我正在使用双[][]mdarray={{3.0, 4.0, 1.0, 8.0},{13.0, 2.0, 12.0, 9.0}测试这个 使用打印方法时,应将其显示为 3.0, 2.0, 1.0, 8.0, 13.0, 4.0, 12.0, 9.0, 使用单独的打印方法输出结果时,数组似乎没有

  • 问题内容: 问题:考虑以下float []: 我想要的是一个int []数组,它表示带有索引的原始数组的顺序。 当然,可以使用自定义比较器,一组自定义对象集或通过简单地对数组进行排序,然后在原始数组中搜索索引(关闭)来完成。 我实际上正在寻找的是Matlab的sort函数的第二个return参数的等效项。 是否有一种简单的方法(<5 LOC)?可能有不需要为每个元素分配新对象的解决方案吗? 更新: