Java 对集合列表进行排序性能提示
我有一个包含对的集合列表,我应该按照集合对键的字母顺序对列表进行排序,我当前的解决方案是通过覆盖add方法对列表进行排序,如下面的代码所示 注意:列表集合对键始终与 汽车,1卡,1 熊,1 所以我只需要获得集合的第一对密钥,就可以对列表进行排序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
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