对馆藏性能提示列表进行排序

时间:2019-06-18 17:13:05

标签: java list performance collections

我有一个包含对的集合列表,我应该按集合对键对列表进行字母排序,我目前的解决方案是通过覆盖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;
        }
    };
}

这是执行我要寻找的最佳性能方法吗?

2 个答案:

答案 0 :(得分:-1)

如果该集合已经排序,并且您要做的就是添加。进行二进制搜索,然后每次要插入list.add(index,element);排序都是不好的。您应该执行一次,然后只需保持良好的插入顺序即可。

添加一些代码以显示bsearch。因为用于收藏的将仅返回匹配项。只提供清单。新对象。以及对列表进行排序的比较器。如果添加许多项,其中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;
}

答案 1 :(得分:-1)

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

通常来说,在确定工作代码的性能不足之前,请先担心优化。首先使事情起作用,然后确定瓶颈在哪里。可能不是排序,而是其他。

Java提供了良好的常规排序算法。您正在与Collections.sort()一起使用。 Java中没有SortedList,but javafx.base contains a SortedList会包装提供的List并保留,并根据实例化时提供的Comparator进行排序。这样可以避免您不得不重写List实现的基本行为。

虽然您的代码似乎可以正常工作,但是这里有一些建议:

    如果对为null,则
  1. pairs.iterator()。next()。getKey()将引发NPE。
  2. 如果对为空,则
  3. pairs.iterator()。next()。getKey()将引发NoSuchElementException。
  4. 如果第一个对具有空键为空,则
  5. pairs.iterator()。next()。getKey()将引发NPE。
  6. 所有这些对于t1都是正确的。
  7. 您正在将pair.iterator()。next()。getKey()与t1.iterator()。next()。toString()比较。一个是对的字符串表示形式,另一个是对中的键。它是否正确?

尽管您的代码可以确保绝对不会发生这些情况,但是以后有人可能对其进行修改,从而带来令人不愉快的意外。您可能想向您的add方法添加验证,以确保不会发生这些情况。通常,当参数无效时抛出IllegalArgumentException是一种很好的做法。

另一种想法:由于您的Collection内容始终相同,并且如果没有两个Collection具有相同种类的Pairs,则应该能够使用SortedMap >>而不是一个列表。如果按键进行比较,则此类Map将为您排序。您将使用第一个配对密钥作为地图/输入密钥put进行收藏。地图的keySet()values()entrySet()都将返回按排序顺序进行迭代的Collection。