Java 对列表进行排序<;数量>;
如何对Java 对列表进行排序<;数量>;,java,list,sorting,collections,Java,List,Sorting,Collections,如何对列表进行排序 示例: List<Number> li = new ArrayList<Number>(); //list of numbers li.add(new Integer(20)); li.add(new Double(12.2)); li.add(new Float(1.2)); List li=new ArrayList()//号码表 加(新整数(20)); 加上(新双(12.2));; li.增加(新浮动(1.2)); Collections.so
列表进行排序
示例:
List<Number> li = new ArrayList<Number>(); //list of numbers
li.add(new Integer(20));
li.add(new Double(12.2));
li.add(new Float(1.2));
List li=new ArrayList()//号码表
加(新整数(20));
加上(新双(12.2));;
li.增加(新浮动(1.2));
Collections.sort(li,新的比较器(){
@凌驾
公共整数比较(数字o1,数字o2){
Double d1=(o1==null)?Double.POSITIVE_无穷大:o1.doubleValue();
Double d2=(o2==null)?Double.POSITIVE_无穷大:o2.doubleValue();
返回d1。比较(d2);
}
});
请看一看解释。在上面的代码中,所有空值和+无穷大值都被处理为移动到末尾
更新1:
List<Number> li = new ArrayList<Number>(); //list of numbers
li.add(new Integer(20));
li.add(new Double(12.2));
li.add(new Float(1.2));
正如和指出了上述实现中的一个缺陷,所以我认为最好限制实现的数量
Collections.sort(li,新的Comparator(){
HashSet您需要一个null
值的解决方案,因为它们可能在集合中-您无法创建不接受null
的对象集合
因此,您可以检查null
并抛出IllegalArgumentException
——其副作用是,您将无法对“污染”列表进行排序,并且必须在运行时处理这些异常
另一个想法是将null
转换为某种数字。我已经展示了这种方法(基于您自己的答案的解决方案)按惯例将任何<代码> null < /代码>转换为<代码>双.NAN/<代码>。还可以考虑将它们转换为<代码> 0 < /代码>或<代码>双。
Collections.sort(li,new Comparator<Number>() {
@Override
public int compare(Number o1, Number o2) {
// null values converted to NaN by convention
Double d1= (o1 == null) ? Double.NaN : o1.doubleValue();
Double d2= (o2 == null) ? Double.NaN : o2.doubleValue();
return d1.compareTo(d2);
}
});
答案很简单:不能。专有数字实现可能比通过getXXX()提供的精度更高或值范围更大为数字接口中的实际值定义的方法。中指出,无法正确实现比较器,因为Number
的实例很可能表示大于Double.MAX\u值的数字(不幸的是,对于Number
接口而言).大于Double.MAX\u值的Number
示例如下
new BigDecimal("" + Double.MAX_VALUE).multiply(BigDecimal.TEN)
但是,下面的解决方案可以处理
Byte
s、Short
s、Integer
s、Long
s、Float
s和Double
s
- 任意大
BigInteger
s
- 任意大的
BigDecimal
s
{Double,Float}.负无限
和{Double,Float}.正无限
请注意,这些值应始终位于任何BigDecimal
之前/之后,即使可能返回Double.NEGATIVE
或Double.NEGATIVE
null
元素
- 上述所有因素的混合物,以及
Number
的未知实现,它也实现了可比性
(这似乎是一个合理的假设,因为标准API中的所有Number
s实现了可比性。)
试试我的java排序算法:
package drawFramePackage;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class QuicksortAlgorithm {
ArrayList<AffineTransform> affs;
ListIterator<AffineTransform> li;
Integer count, count2;
/**
* @param args
*/
public static void main(String[] args) {
new QuicksortAlgorithm();
}
public QuicksortAlgorithm(){
count = new Integer(0);
count2 = new Integer(1);
affs = new ArrayList<AffineTransform>();
for (int i = 0; i <= 128; i++) {
affs.add(new AffineTransform(1, 0, 0, 1, new Random().nextInt(1024), 0));
}
affs = arrangeNumbers(affs);
printNumbers();
}
public ArrayList<AffineTransform> arrangeNumbers(ArrayList<AffineTransform> list) {
while (list.size() > 1 && count != list.size() - 1) {
if (list.get(count2).getTranslateX() > list.get(count).getTranslateX()) {
list.add(count, list.get(count2));
list.remove(count2 + 1);
}
if (count2 == list.size() - 1) {
count++;
count2 = count + 1;
} else {
count2++;
}
}
return list;
}
public void printNumbers(){
li = affs.listIterator();
while (li.hasNext()) {
System.out.println(li.next());
}
}
}
package-drawFramePackage;
导入java.awt.geom.AffineTransform;
导入java.util.ArrayList;
导入java.util.ListIterator;
导入java.util.Random;
公共类快速排序算法{
ArrayList affs;
列表迭代器李;
整数计数,count2;
/**
*@param args
*/
公共静态void main(字符串[]args){
新的QuicksortAlgorithm();
}
公共QuicksortAlgorithm(){
计数=新整数(0);
count2=新整数(1);
affs=新的ArrayList();
对于(int i=0;i 1&&count!=list.size()-1){
if(list.get(count2.getTranslateX()>list.get(count.getTranslateX()){
list.add(count,list.get(count2));
列表。删除(count2+1);
}
if(count2==list.size()-1){
计数++;
count2=count+1;
}否则{
count2++;
}
}
退货清单;
}
公共数字(){
li=affs.listIterator();
while(li.hasNext()){
System.out.println(li.next());
}
}
}
请注意,如果两个值相距太远,则该操作将失败。我将转换为两个值并对其调用compareTo,或者使用大于/小于运算符。@Andreas\D:空值无论如何都会引发异常。您有更好的方法来处理它吗?@Emil:在那里设置一个条件,这样所有null
最终都会消失。以下是我的想法:在compare
方法中,检查o1和o2是否是compariable
的instanceof
。如果是,那么Java代码已经实现了数字类型的最佳比较-使用该方法(通过调用o1.comparieto(o2)
。如果它没有实现可比性
,我建议使用大十进制
而不是双十进制
。好问题+1,但坏答案,-1。使用aioobe提供的解决方案-它有效,这不行!@Emil:没有编写大量明显的代码就不行。如果有两个数字实例具有内部值“Double.MAX_VALUE*2”和“Double.MAX_VALUE*3”。它们的getDouble()实现必须截断该值以适应double的范围,因此可能两者都返回double.MAX_值,从而无法为这些类型实现通用比较器。@jarnbjo:你是说BigDecimal或BigInteger的数字实例吗?@Emil:它们只是示例。任何人都可以编写自己的比较器实现e Number接口,您不必只考虑标准API中的类。@jarnbjo:是的,我明白。还有什么吗
@SuppressWarnings("unchecked")
class NumberComparator implements Comparator<Number> {
// Special values that are treated as larger than any other.
private final static List<?> special =
Arrays.asList(Double.NaN, Float.NaN, null);
private final static List<?> largest =
Arrays.asList(Double.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
private final static List<?> smallest =
Arrays.asList(Double.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
public int compare(Number n1, Number n2) {
// Handle special cases (including null)
if (special.contains(n1)) return 1;
if (special.contains(n2)) return -1;
if (largest.contains(n1) || smallest.contains(n2)) return 1;
if (largest.contains(n2) || smallest.contains(n1)) return -1;
// Promote known values (Byte, Integer, Long, Float, Double and
// BigInteger) to BigDecimal, as this is the most generic known type.
BigDecimal bd1 = asBigDecimal(n1);
BigDecimal bd2 = asBigDecimal(n2);
if (bd1 != null && bd2 != null)
return bd1.compareTo(bd2);
// Handle arbitrary Number-comparisons if o1 and o2 are of same class
// and implements Comparable.
if (n1 instanceof Comparable<?> && n2 instanceof Comparable<?>)
try {
return ((Comparable) n1).compareTo((Comparable) n2);
} catch (ClassCastException cce) {
}
// If the longValue()s differ between the two numbers, trust these.
int longCmp = ((Long) n1.longValue()).compareTo(n2.longValue());
if (longCmp != 0)
return longCmp;
// Pray to god that the doubleValue()s differ between the two numbers.
int doubleCmp = ((Double) n1.doubleValue()).compareTo(n2.doubleValue());
if (doubleCmp != 0)
return longCmp;
// Die a painful death...
throw new UnsupportedOperationException(
"Cannot compare " + n1 + " with " + n2);
}
// Convert known Numbers to BigDecimal, and the argument n otherwise.
private BigDecimal asBigDecimal(Number n) {
if (n instanceof Byte) return new BigDecimal((Byte) n);
if (n instanceof Integer) return new BigDecimal((Integer) n);
if (n instanceof Short) return new BigDecimal((Short) n);
if (n instanceof Long) return new BigDecimal((Long) n);
if (n instanceof Float) return new BigDecimal((Float) n);
if (n instanceof Double) return new BigDecimal((Double) n);
if (n instanceof BigInteger) return new BigDecimal((BigInteger) n);
if (n instanceof BigDecimal) return (BigDecimal) n;
return null;
}
}
public class Main {
public static void main(String[] args) {
List<Number> li = new ArrayList<Number>();
// Add an Integer, a Double, a Float, a Short, a Byte and a Long.
li.add(20); li.add((short) 17);
li.add(12.2); li.add((byte) 100);
li.add(0.2f); li.add(19518926L);
li.add(Double.NaN); li.add(Double.NEGATIVE_INFINITY);
li.add(Float.NaN); li.add(Double.POSITIVE_INFINITY);
// A custom Number
li.add(new BoolNumber(1));
li.add(new BoolNumber(0));
// Add two BigDecimal that are larger than Double.MAX_VALUE.
BigDecimal largeDec = new BigDecimal("" + Double.MAX_VALUE);
li.add(largeDec/*.multiply(BigDecimal.TEN)*/);
li.add(largeDec.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN));
// Add two BigInteger that are larger than Double.MAX_VALUE.
BigInteger largeInt = largeDec.toBigInteger().add(BigInteger.ONE);
li.add(largeInt.multiply(BigInteger.TEN));
li.add(largeInt.multiply(BigInteger.TEN).multiply(BigInteger.TEN));
// ...and just for fun...
li.add(null);
Collections.shuffle(li);
Collections.sort(li, new NumberComparator());
for (Number num : li)
System.out.println(num);
}
static class BoolNumber extends Number {
boolean b;
public BoolNumber(int i) { b = i != 0; }
public double doubleValue() { return b ? 1d : 0d; }
public float floatValue() { return b ? 1f : 0f; }
public int intValue() { return b ? 1 : 0; }
public long longValue() { return b ? 1L : 0L; }
public String toString() { return b ? "1" : "0"; }
}
}
-Infinity
0
0.2
1
12.2
17
20
100
19518926
1.7976931348623157E+308
17976931348623157000000000...00000000010
1.797693134862315700E+310
179769313486231570000000000000...00000100
Infinity
NaN
null
NaN
package drawFramePackage;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class QuicksortAlgorithm {
ArrayList<AffineTransform> affs;
ListIterator<AffineTransform> li;
Integer count, count2;
/**
* @param args
*/
public static void main(String[] args) {
new QuicksortAlgorithm();
}
public QuicksortAlgorithm(){
count = new Integer(0);
count2 = new Integer(1);
affs = new ArrayList<AffineTransform>();
for (int i = 0; i <= 128; i++) {
affs.add(new AffineTransform(1, 0, 0, 1, new Random().nextInt(1024), 0));
}
affs = arrangeNumbers(affs);
printNumbers();
}
public ArrayList<AffineTransform> arrangeNumbers(ArrayList<AffineTransform> list) {
while (list.size() > 1 && count != list.size() - 1) {
if (list.get(count2).getTranslateX() > list.get(count).getTranslateX()) {
list.add(count, list.get(count2));
list.remove(count2 + 1);
}
if (count2 == list.size() - 1) {
count++;
count2 = count + 1;
} else {
count2++;
}
}
return list;
}
public void printNumbers(){
li = affs.listIterator();
while (li.hasNext()) {
System.out.println(li.next());
}
}
}