使用比较器进行自定义排序

问题描述:

我想开发汽车列表的排序演示。我正在使用数据表来显示汽车列表。现在实际上我想按汽车颜色对列表进行排序。这里不按字母顺序排序。我想使用我的自定义排序顺序,如红色汽车先来,然后蓝色等。使用比较器进行自定义排序

为此,我尝试使用Java比较和可比较,但它只允许按字母顺序排序。

那么,任何人都可以指导我实现使用该技术的方式,以便排序变得更快。

import java.util.ArrayList; 
import java.util.Comparator; 
import java.util.List;  

public class CarSort implements Comparable<CarSort>{ 

    String name; 
    String color; 

    public CarSort(String name, String color){ 
     this.name = name; 
     this.color = color; 
    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getColor() { 
     return color; 
    } 
    public void setColor(String color) { 
     this.color = color; 
    } 

    //Implement the natural order for this class 
    public int compareTo(CarSort c) 
    { 
     return getName().compareTo(c.getName()); 
    } 

    static class ColorComparator implements Comparator<CarSort> 
    {    
     public int compare(CarSort c1, CarSort c2) 
     { 
      String a1 = c1.getColor(); 
      String a2 = c2.getColor(); 
      return a1.compareTo(a2); 
     } 
    } 

    public static void main(String[] args) 
    { 
     List<CarSort> carList = new ArrayList<CarSort>(); 
     List<String> sortOrder = new ArrayList<String>(); 

     carList.add(new CarSort("Ford Figo","Silver")); 
     carList.add(new CarSort("Santro","Blue")); 
     carList.add(new CarSort("Honda Jazz","Magenta")); 
     carList.add(new CarSort("Indigo V2","Red")); 

     sortOrder.add("Red"); 
     sortOrder.add("Magenta"); 
     sortOrder.add("Blue"); 
     sortOrder.add("Silver");    

     // Now here I am confuse how to implement my custom sort    
    } 
} 

我建议你创建你的车的颜色,而不是使用字符串和枚举的自然顺序将在其声明中的常量的顺序枚举。

public enum PaintColors { 
    SILVER, BLUE, MAGENTA, RED 
} 

static class ColorComparator implements Comparator<CarSort> 
{ 
    public int compare(CarSort c1, CarSort c2) 
    { 
     return c1.getColor().compareTo(c2.getColor()); 
    } 
} 

你改变了字符串PaintColor,然后在主你的车列表变成:

carList.add(new CarSort("Ford Figo",PaintColor.SILVER)); 

... 

Collections.sort(carList, new ColorComparator()); 
+0

如何将我运行此example.PaintColors在ColorComparator.could不访问您说明了如何的主要方法会是什么样子。 – Deepak 2011-03-09 11:42:43

+0

输出是什么?它总是首先是银色的? – Deepak 2011-03-09 11:49:51

+0

@Deepak:是的,enum值的自然顺序是其值的定义顺序。 – 2011-03-09 12:17:42

我认为这可以如下进行:

class ColorComparator implements Comparator<CarSort> 
{ 
    private List<String> sortOrder; 
    public ColorComparator (List<String> sortOrder){ 
     this.sortOrder = sortOrder; 
    } 

    public int compare(CarSort c1, CarSort c2) 
    { 
      String a1 = c1.getColor(); 
      String a2 = c2.getColor(); 

      return sortOrder.indexOf(a1) - sortOrder.indexOf(a2); 
    } 
} 

对于分拣使用t他:

Collections.sort(carList, new ColorComparator(sortOrder)); 

P. S.我在不调试它的浏览器中编写了这段代码。但是这个概念应该清楚。

+0

嗨ilya,谢谢你...这是非常简单和伟大的方式。 – akhtar 2011-03-09 13:11:10

如何:

List<String> definedOrder = // define your custom order 
    Arrays.asList("Red", "Green", "Magenta", "Silver"); 

Comparator<Car> comparator = new Comparator<Car>(){ 

    @Override 
    public int compare(final Car o1, final Car o2){ 
     // let your comparator look up your car's color in the custom order 
     return Integer.valueOf(
      definedOrder.indexOf(o1.getColor())) 
      .compareTo(
       Integer.valueOf(
        definedOrder.indexOf(o2.getColor()))); 
    } 
}; 

原则上,我同意使用enum是一个更好的办法,但这个版本更加灵活,因为它可以让你定义不同的排序顺序。

更新

Guava具有此功能内置到其Ordering类:

List<String> colorOrder = ImmutableList.of("red","green","blue","yellow"); 
final Ordering<String> colorOrdering = Ordering.explicit(colorOrder); 
Comparator<Car> comp = new Comparator<Car>() { 
    @Override 
    public int compare(Car o1, Car o2) { 
     return colorOrdering.compare(o1.getColor(),o2.getColor()); 
    } 
}; 

这个版本是有点更简洁。


再次更新

的Java 8使比较甚至更少详细:符合

Comparator<Car> carComparator = Comparator.comparing(
     c -> definedOrder.indexOf(c.getColor())); 

比较...

List<Object> objList = findObj(name); 
Collections.sort(objList, new Comparator<Object>() { 
    @Override 
    public int compare(Object a1, Object a2) { 
     return a1.getType().compareToIgnoreCase(a2.getType()); 
    } 
}); 

我必须做同样的事情Sean和ilalex的回答。
但我有太多的选项来明确定义排序顺序,并且只需要将某些条目浮动到列表的前面......以指定的(非自然的)顺序。
希望这对别人有帮助。

public class CarComparator implements Comparator<Car> { 

    //sort these items in this order to the front of the list 
    private static List<String> ORDER = Arrays.asList("dd", "aa", "cc", "bb"); 

    public int compare(final Car o1, final Car o2) { 
     int result = 0; 
     int o1Index = ORDER.indexOf(o1.getName()); 
     int o2Index = ORDER.indexOf(o2.getName()); 
     //if neither are found in the order list, then do natural sort 
     //if only one is found in the order list, float it above the other 
     //if both are found in the order list, then do the index compare 
     if (o1Index < 0 && o2Index < 0) result = o1.getName().compareTo(o2.getName()); 
     else if (o1Index < 0) result = 1; 
     else if (o2Index < 0) result = -1; 
     else result = o1Index - o2Index; 
     return result; 
    } 

//Testing output: dd,aa,aa,cc,bb,bb,bb,a,aaa,ac,ac,ba,bd,ca,cb,cb,cd,da,db,dc,zz 
} 

在Java 8,你可以做这样的事情:

首先,您需要一个枚举:

public enum Color { 
    BLUE, YELLOW, RED 
} 

车类:

public class Car { 

    Color color; 

    .... 

    public Color getColor() { 
     return color; 
    } 

    public void setColor(Color color) { 
     this.color = color; 
    } 
} 

,然后使用你的车列表,你可以简单地做:

Collections.sort(carList, Comparator:comparing(CarSort::getColor)); 
+0

这不是一个自定义排序。 – zygimantus 2017-04-12 11:19:57

+0

此外,它不是一个“功能”的做法...这有副作用! – Programmer 2017-11-16 04:39:58

定义一个枚举类型作为colorString

public enum Colors { 
    BLUE, SILVER, MAGENTA, RED 
} 

变更数据类型到吸气剂和颜色的设置器方法的Colors 变化返回类型和参数类型到Colors

定义比较器类型如下

static class ColorComparator implements Comparator<CarSort> 
{ 
    public int compare(CarSort c1, CarSort c2) 
    { 
     return c1.getColor().compareTo(c2.getColor()); 
    } 
} 

将元素添加到List之后,调用通过传递列表和比较对象作为参数的收集排序方法

Collections.sort(carList, new ColorComparator()); 然后使用ListIterator打印。

满级实现如下:

package test; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List;  
import java.util.ListIterator; 

public class CarSort implements Comparable<CarSort>{ 

    String name; 
    Colors color; 

    public CarSort(String name, Colors color){ 
     this.name = name; 
     this.color = color; 
    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public Colors getColor() { 
     return color; 
    } 
    public void setColor(Colors color) { 
     this.color = color; 
    } 

    //Implement the natural order for this class 
    public int compareTo(CarSort c) 
    { 
     return getName().compareTo(c.getName()); 
    } 

    static class ColorComparator implements Comparator<CarSort> 
    { 
     public int compare(CarSort c1, CarSort c2) 
     { 
      return c1.getColor().compareTo(c2.getColor()); 
     } 
    } 

    public enum Colors { 
     BLUE, SILVER, MAGENTA, RED 
    } 

    public static void main(String[] args) 
    { 
     List<CarSort> carList = new ArrayList<CarSort>(); 
     List<String> sortOrder = new ArrayList<String>(); 

     carList.add(new CarSort("Ford Figo",Colors.SILVER)); 
     carList.add(new CarSort("Santro",Colors.BLUE)); 
     carList.add(new CarSort("Honda Jazz",Colors.MAGENTA)); 
     carList.add(new CarSort("Indigo V2",Colors.RED)); 
     Collections.sort(carList, new ColorComparator()); 

     ListIterator<CarSort> itr=carList.listIterator(); 
     while (itr.hasNext()) { 
      CarSort carSort = (CarSort) itr.next(); 
      System.out.println("Car colors: "+carSort.getColor()); 
     } 
    } 
}