Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.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_List_Performance_Collections - Fatal编程技术网

Java 对集合列表进行排序性能提示

Java 对集合列表进行排序性能提示,java,list,performance,collections,Java,List,Performance,Collections,我有一个包含对的集合列表,我应该按照集合对键的字母顺序对列表进行排序,我当前的解决方案是通过覆盖add方法对列表进行排序,如下面的代码所示 注意:列表集合对键始终与 汽车,1卡,1 熊,1 所以我只需要获得集合的第一对密钥,就可以对列表进行排序 List<Collection<Pair<String, Integer>>> shufflingResult; public void init() { shufflingResult = new Arra

我有一个包含对的集合列表,我应该按照集合对键的字母顺序对列表进行排序,我当前的解决方案是通过覆盖add方法对列表进行排序,如下面的代码所示

注意:列表集合对键始终与

汽车,1卡,1

熊,1

所以我只需要获得集合的第一对密钥,就可以对列表进行排序

List<Collection<Pair<String, Integer>>> shufflingResult;

public void init() {
    shufflingResult = new ArrayList<>() {
        public boolean add(Collection<Pair<String, Integer>> c) {
            super.add(c);
            Collections.sort(shufflingResult, new Comparator<Collection<Pair<String, Integer>>>() {
                @Override
                public int compare(Collection<Pair<String, Integer>> pairs, Collection<Pair<String, Integer>> t1) {
                    return pairs.iterator().next().getKey().compareTo(t1.iterator().next().toString());
                }
            });
            return true;
        }
    };
}

这是我想要的最好的性能方法吗?

如果集合已经排序,您只需要添加。进行二进制搜索,然后只使用list.addindex,element;每次要插入时进行排序都不好。您应该做一次,然后保持良好的插入顺序

添加一些代码以显示B搜索。因为用于集合的将只返回匹配项。只需提供清单。新对象。还有一个比较器,它可以根据您的需要对列表进行排序。如果在N>列表当前大小的位置添加许多项,则最好添加所有项,然后进行排序

private static void add(List<ThingObject> l, ThingObject t, Comparator<ThingObject> c) {
    if (l != null) {
        if (l.size() == 0) {
            l.add(t);
        } else {
            int index = bSearch(l, t, c);
            l.add(index, t);
        }
    }
}

private static int bSearch(List<ThingObject> l, ThingObject t, Comparator<ThingObject> c) {
    boolean notFound = true;
    int high = l.size() - 1;
    int low = 0;
    int look = (low + high) / 2;
    while (notFound) {
        if (c.compare(l.get(look), t) > 0) {
            // it's to the left of look
            if (look == 0 || c.compare(l.get(look - 1), t) < 0) {
                //is it adjacent?
                notFound = false;
            } else {
                //look again.
                high = look - 1;
                look = (low + high) / 2;
            }
        } else if (c.compare(l.get(look), t) < 0) {
            // it's to the right of look
            if (look == l.size() - 1 || c.compare(l.get(look + 1), t) > 0) {
                //is it adjacent?
                look = look + 1;
                notFound = false;
            } else {
                //look again.
                low = look + 1;
                look = (low + high) / 2;
            }
        } else {
            notFound = false;
        }

    }
    return look;
}

表演是一件棘手的事情。最佳排序算法在很大程度上取决于数据的数量和类型,以及数据的随机程度。有些算法对于部分排序的数据是最好的,而另一些算法对于真正的随机数据是最好的

一般来说,在确定工作代码的性能不足之前,请担心优化问题。首先让事情运转起来,然后确定瓶颈在哪里。它可能不是排序,而是别的

Java提供了良好的通用排序算法。您正在将其与Collections.sort一起使用。Java中没有SortedList,它包装提供的列表,并根据实例化时提供的比较器进行排序。这将避免您必须重写列表实现的基本行为

虽然您的代码似乎可以工作,但这里有几个建议:

如果pairs为null,pairs.iterator.next.getKey将抛出NPE。 如果pairs为空,则pairs.iterator.next.getKey将抛出NoSuchElementException。 如果第一对的null键为空,pairs.iterator.next.getKey将抛出NPE。 所有这些对于t1也是如此。 您正在将pairs.iterator.next.getKey与t1.iterator.next.toString进行比较。一个是对的字符串表示,另一个是对中的密钥。这是正确的吗? 虽然您的代码可以确保这些情况永远不会发生,但稍后可能会有人对其进行修改,从而导致令人不快的意外。您可能希望向add方法添加验证,以确保这些情况不会发生。当参数无效时抛出IllegalArgumentException通常是一种好的做法


另一个想法是:由于您的集合内容总是相同的,并且如果没有两个集合具有相同类型的对,那么您应该能够使用SortedMap而不是列表。如果您按键进行比较,这种地图将为您排序。您将使用第一对密钥作为映射/输入密钥放置集合。映射的键集、值和入口集都将返回按排序顺序迭代的集合。

Java将按其排序方式进行排序。这与相关操作的性能无关。使用SortedList是一个不错的选择,可能也是一个不错的选择。但是没有提到每次排序都是不好的。默认的Arrays.sort搜索算法就是Collections.sort调用的DualPivotQuickSort。在许多情况下,此版本的快速排序的降级程度不如快速排序严重,而且通常性能更高。快速排序和二进制搜索都会影响logn的性能。Java很好。不相关的列表集合大小有多大?如果它们很小,InsertionSort将优于MergeSort、QuickSort等,尤其是在部分/大部分已排序的集合上,如果您在每次插入时进行排序,您将拥有这些集合。二进制搜索是logn而不是nLogn,因此,如果已经排序,它会更好。一般来说,在确定工作代码的性能不足之前,请担心优化问题。为什么你只会担心到事情变得糟糕的地步呢。似乎这是最值得关注的时候了。AFAIK DualPivotQuickSort只用于基本体。对于对象,Java保证了稳定的排序,这就排除了快速排序。取而代之的是使用TimSort,它可以很好地处理已经排序的序列。这在OP的情况下很有用,因为它们的add的复杂性是On而不是*logn