简体   繁体   English

排序集合性能提示列表

[英]Sorting a list of collections performance tips

I have a list of collections that contains pairs, I should keep the list sorted alphabetically by it's collections pairs key, My current solution is keeping the list sorted by overriding the add method, Like the code below. 我有一个包含对的集合列表,我应该按集合对键对列表进行字母排序,我目前的解决方案是通过覆盖add方法来对列表进行排序,就像下面的代码一样。

Note: the list collections pairs key are always the same like 注意:列表集合对键始终相同

(Car,1)(Car,1) (汽车,1)(汽车,1)

(Bear,1) (熊1)

So i just need to get first pair key of collections to get it sorting the list 所以我只需要获取集合的第一对密钥就可以对列表进行排序

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;
        }
    };
}

Is this the best performance way to do what i'm looking for? 这是执行我要寻找的最佳性能方法吗?

If the collection is already sorted and all you want to do is add. 如果该集合已经排序并且您要做的就是添加。 do a binary search and then just use list.add(index,element); 做一个二进制搜索,然后只使用list.add(index,element); sorting every time you want to insert is bad. 每次插入时排序都是不好的。 you should do it once and then just maintain with good insertion order. 您应该执行一次,然后只需保持良好的插入顺序即可。

adding some code to show the bsearch. 添加一些代码以显示bsearch。 as the one for collections will only return matches. 因为用于收藏的将仅返回匹配项。 just supply the list. 只提供清单。 the new object. 新对象。 and the comparator that sorts the list how you want it. 以及对列表进行排序的比较器。 if adding many items where N> current size of the list probably better to add all then sort. 如果添加许多项,其中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;
}

Performance is a tricky thing. 性能是一件棘手的事情。 The best sort algorithm will depend largely on the volume and type of data, and to what degree it is random. 最佳排序算法将在很大程度上取决于数据的数量和类型,以及在何种程度上是随机的。 Some algorithms are best when Data which is partially sorted, others for truly random data. 对于部分排序的数据,某些算法是最好的,而对于真正的随机数据,有些算法是最好的。

Generally speaking, worry about optimization until you've determined that working code is not sufficiently performant. 一般来说,在确定工作代码的性能不足之前,请担心优化问题。 Get things working first, and then determine where the bottleneck it. 首先使事情起作用,然后确定瓶颈在哪里。 It may not be sorting, but something else. 它可能不是排序,而是其他。

Java provides good general sorting algorithms. Java提供了良好的常规排序算法。 You're using one with Collections.sort(). 您正在与Collections.sort()一起使用。 There is no SortedList in Java, but javafx.base contains a SortedList which wraps a supplied List and keeps is sorted based on a Comparator supplied at instantiation. Java中没有SortedList, 但是javafx.base包含SortedList该SortedList包装提供的List,并根据实例化时提供的Comparator对其进行排序。 This would prevent you from having to override the base behavior of the List implementation. 这样可以避免您不得不重写List实现的基本行为。

While your code seems like it may work, here's a couple of suggestions: 尽管您的代码似乎可以正常工作,但这里有一些建议:

  1. pairs.iterator().next().getKey() will throw an NPE if pairs is null. 如果pairs为null,则pairs.iterator()。next()。getKey()将抛出一个NPE。
  2. pairs.iterator().next().getKey() will throw an NoSuchElementException if pairs is empty. 如果对为空,则pairs.iterator()。next()。getKey()将引发NoSuchElementException。
  3. pairs.iterator().next().getKey() will throw an NPE if the first Pair has a null key is empty. 如果第一个对具有空键为空,则pairs.iterator()。next()。getKey()将引发NPE。
  4. All of this is true for t1 as well. 所有这些对于t1也是正确的。
  5. You're comparing pairs.iterator().next().getKey() to t1.iterator().next().toString(). 您正在将pair.iterator()。next()。getKey()与t1.iterator()。next()。toString()比较。 One is the String representation of the Pair, and the other is the Key from the Pair. 一个是对的字符串表示形式,另一个是对中的键。 Is this correct? 这个对吗?

While your code may make sure these conditions never happen, someone may modify it later with resulting unpleasant surprises. 尽管您的代码可以确保永远不会发生这些情况,但是以后有人可能对其进行修改,从而带来令人不愉快的意外。 You may want to add validations to your add method to ensure that these cases won't occur. 您可能想向您的add方法添加验证,以确保不会发生这些情况。 Throwing IllegalArgumentException when arguments aren't valid is generally good practice. 通常,当参数无效时抛出IllegalArgumentException。

Another thought: Since your Collection contents are always the same, and if no two Collections have the same kind of Pairs, you should be able to use a SortedMap<String, Collection<Pair<String,Integer>>> instead of a List. 另一个想法:由于您的Collection内容始终相同,并且如果没有两个Collection具有相同的Pairs类型,则应该可以使用SortedMap <String,Collection <Pair <String,Integer >>>而不是List。 If you are comparing by Key this sort of Map will keep things sorted for you. 如果按键进行比较,则此类Map将为您排序。 You'll put the Collection using the first Pair's Key as the map/entry key. 您将使用第一个配对键作为地图/输入键put收藏。 The map's keySet() , values() and entrySet() will all return Collections which iterate in sorted order. 映射的keySet()values()entrySet()都将返回按排序顺序进行迭代的Collections。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM