相关疑难解决方法(0)

为什么Java中没有SortedList?

在Java中有SortedSetSortedMap接口.两者都属于Java的标准集合框架,并提供了一种访问元素的排序方式.

但是,根据我的理解SortedList,Java中没有.您可以使用java.util.Collections.sort()对列表进行排序.

知道为什么它的设计是这样的吗?

java sorting collections

479
推荐指数
6
解决办法
44万
查看次数

Java中的排序数组列表

我很困惑,我找不到快速的答案.我基本上在Java中寻找一个实现java.util.List接口的数据结构,但它以排序顺序存储其成员.我知道你可以使用普通ArrayList并使用Collections.sort()它,但我有一个场景,我偶尔会添加并经常从我的列表中检索成员,我不希望每次检索成员时都要对它进行排序,以防万一新增了一个.有人能指出我存在于JDK甚至第三方库中的这样的东西吗?

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

答案摘要:我发现所有这些都非常有趣并且学到了很多东西.Aioobe尤其值得一提,因为他坚持不懈地努力实现上述要求(主要是支持重复的有序java.util.List实现).我已经接受了他的答案,因为我提出的问题是最准确的,而且最让我发现的是我正在寻找的内容的影响,即使我问的不完全是我所需要的.

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

该接口的用户可以精确控制列表中每个元素的插入位置.

插入排序列表无法精确控制插入点.然后,你必须考虑如何处理一些方法.就拿add例如:

public boolean add(Object o)

 Appends the specified element to the end of this list (optional operation).
Run Code Online (Sandbox Code Playgroud)

你现在处于令人不安的境地:1)打破合同并实现添加的排序版本2)让add一个元素添加到列表的末尾,打破你的排序顺序3)add抛出(作为其可选)抛出一UnsupportedOperationException和实施这增加了在一个有序的物品的另一种方法.

选项3可能是最好的,但我发现它有一个你不能使用的添加方法和另一个不在界面中的sortedAdd方法令人讨厌.

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

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

java sorted data-structures

83
推荐指数
6
解决办法
10万
查看次数

Java:排序集合允许重复,具有内存效率并提供快速插入和更新

具体来说,我需要一个集合,它使用一个字段A进行访问,使用另一个字段(字段S)进行排序,但是接受重复的已排序集合就足够了.

我经常到这一点,我需要这个集合,TreeMap不是一个选项,因为它不允许重复.所以现在是时候问这里了.stackoverflow 在这里这里指出了几种解决方法- 即:

  • PriorityQueue:缓慢更新(remove(Object)+ add(Object))和原始键的装箱
  • 斐波纳契堆:内存浪费(?)
  • TreeMap<Field_S, List<Value>>:对我来说问题是列表的内存开销和原始键的装箱
  • 排序列表或数组:问题是慢插入和删除 - >我应该实现一个分段排序列表?
  • 来自guava(docs)的TreeMultimap:外部依赖和可能内存效率低下(?)

谁有更好的建议?或者我应该对自己的排序数据结构(哪一个?)起作用?其他来源(Java,开源,单元测试和小deps)也不错.


更新

关于我目前用例的更多细节(虽然我上次有类似的需求).我有一个集合(有数百万)我想要的参考

  • 轮询或获得关于字段S的最小元素
  • 并在字段A的帮助下更新字段S.
  • 字段S的相同值可能发生.字段A实际上是指向另一个数组的整数
  • 我想要的唯一依赖是trove4j.如果需要,我可以使用不同的mahout集合.但不是番石榴,因为虽然是一个很好的lib,但是这些集合并没有被调整为内存效率(装箱/拆箱).

所以对于斐波那契堆的所有呼声,但我担心它每个元素的开销太多 - >这就是我考虑更高效的"排序+分段数组"解决方案的原因.

java data-structures

20
推荐指数
2
解决办法
2万
查看次数

列出维护排序的实现

ListJava中是否存在基于提供的维护顺​​序的现有实现Comparator

可以通过以下方式使用的东西:

Comparator<T> cmp = new MyComparator<T>();
List<T> l = new OrderedList<T>(cmp);
l.add(someT);
Run Code Online (Sandbox Code Playgroud)

使得someT被插入,使得在列表中的顺序是根据保持cmp

(关于@andersoj的建议我正在完成我的问题,还有一个请求)

此外,我希望能够按排序顺序遍历列表而不删除元素,即:

T min = Const.SMALLEST_T;
for (T e: l) {
  assertTrue(cmp.compare(min, e) >= 0);
  min = e;
}
Run Code Online (Sandbox Code Playgroud)

应该通过.

欢迎所有的建议(除了告诉我Collections.sort在无序的完整列表中使用),但是,我更喜欢某些内容java.*或最终,org.apache.*因为此时很难引入新的库.

注意:(UPDATE4)我意识到这种列表的实现性能不足.有两种一般方法:

  1. 使用链接结构(种类)B树或类似物
  2. 使用数组和插入(使用二进制搜索)

没有1. CPU缓存未命中问题No 2.在数组中移位元素有问题.

UPDATE2: TreeSet不起作用,因为它使用提供的比较器(MyComparator)来检查是否相等,并基于它假设元素相等并排除它们.我需要那个比较器只用于排序,而不是"唯一性"过滤(因为元素按其自然顺序不相等)

UPDATE3: PriorityQueue不能正常工作List(因为我需要),因为没有办法按照"排序"的顺序遍历它,要按排序顺序获取元素,你必须从集合中删除它们.

更新:

类似的问题:
Java中Java 排序数组列表的良好排序列表

java collections list insertion-order

16
推荐指数
2
解决办法
5万
查看次数

Java列表,在我添加元素时自动对元素进行排序

可能重复:
java中的排序集合

我想知道Java中是否有内置类允许我添加自动排序的元素.如果两个元素的排名相同,则排序应保留添加顺序.我认为这将是一个优先级队列,但不应该"弹出"元素,我希望它们留在列表中.

显然我可以自己实现这个,但我宁愿使用Java语言实现的东西(更少的bug测试/对未来的项目也很好,而不是导入我自己的代码).

如果在语言中没有这样的东西,我也会对第三方来源感兴趣.

java list data-structures

12
推荐指数
1
解决办法
4万
查看次数

允许重复的TreeSet或TreeMap

我需要一个Collection对元素进行排序,但不会删除重复项.

我已经去了TreeSet,因为TreeSet实际上将值添加到支持TreeMap:

public boolean add(E e) {
    return m.put(e, PRESENT)==null;
}
Run Code Online (Sandbox Code Playgroud)

TreeMap使用Comparators compare逻辑删除重复项

我写了一个Comparator在相同元素的情况下返回1而不是0.因此,在相同元素的情况下,TreeSet使用它Comparator不会覆盖副本,只会对其进行排序.

我已经测试了它的简单String对象,但我需要一组自定义对象.

public static void main(String[] args)
{       
        List<String> strList = Arrays.asList( new String[]{"d","b","c","z","s","b","d","a"} );      
        Set<String> strSet = new TreeSet<String>(new StringComparator());       
        strSet.addAll(strList);     
        System.out.println(strSet); 
}

class StringComparator implements Comparator<String>
{
    @Override
    public int compare(String s1, String s2)
    {
        if(s1.compareTo(s2) == 0){
            return 1;
        }
        else{
            return s1.compareTo(s2);
        }
    }
} …
Run Code Online (Sandbox Code Playgroud)

java collections treemap treeset

8
推荐指数
2
解决办法
2万
查看次数

Java集合binarySearch无法正常工作

我只是想尝试使用原生Java二进制搜索,希望它总能找到第一次出现.但它并不总是第一次出现,我在这里做错了什么?

import java.util.*;

class BinarySearchWithComparator
{
  public static void main(String[] args)
  {
    // Please scroll down to see 'User' class implementation.
    List<User> l = new ArrayList<User>();
    l.add(new User(10, "A"));
    l.add(new User(10, "A"));
    l.add(new User(10, "A"));

    l.add(new User(20, "B"));
    l.add(new User(20, "B"));
    l.add(new User(20, "B"));
    l.add(new User(20, "B"));
    l.add(new User(20, "B"));
    l.add(new User(20, "B"));
    l.add(new User(20, "B"));


    l.add(new User(30, "C"));
    l.add(new User(30, "C"));
    l.add(new User(30, "C"));
    l.add(new User(30, "C"));

    Comparator<User> c = new Comparator<User>() {
      public int compare(User u1, User u2) …
Run Code Online (Sandbox Code Playgroud)

java collections binary-search

3
推荐指数
2
解决办法
5509
查看次数

Java 对象上的任意比较器

假设我正在构建一个TreeSet对象,其顺序仅取决于一个值。

我不能做

TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX));
Run Code Online (Sandbox Code Playgroud)

因为如果我添加两个Foo具有相同对象的不同对象x,那么一个将替换另一个(即,如果我这样做,tree.add(foo1)并且,将代替)。tree.add(foo2)tree.size()12

我可以比较 的每个字段Foo,但我希望 的两个实例Foo被视为不同,即使每个字段都相同。

一种“几乎有效”的解决方案是

TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX).thenComparing(Foo::hashCode));
Run Code Online (Sandbox Code Playgroud)

但当存在哈希冲突时,这会失败。

总之,我正在寻找类似的东西

TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX).thenComparing(Foo::getInternalAddress));
Run Code Online (Sandbox Code Playgroud)

但我们当然无法使用这样的方法。

解决方法

我知道有解决方法:

  • 如果我不关心对象本身,而只关心树中有多少个,我可以使用多重集TreeMap<Foo, Integer>(并比较所有字段)来给出Foo特定对象的数量x
  • 如果我确实关心对象(我正在进行引用相等性检查),我可以使用不同的多重集TreeMap<Foo, List<Foo>>(或TreeMap<Integer, List<Foo>>键为x)。但如果“重复”的 foo 很少,那么所有单例列表都会浪费空间。

因此,虽然我知道 a 有解决方法TreeMap,但我仍然想知道是否有一种方法可以仅使用 a 来做到这一点TreeSet

java comparator treeset

3
推荐指数
1
解决办法
233
查看次数