如何根据其中一个参数对数据结构进行不同的排序?

时间:2017-05-12 06:16:31

标签: java sorting

让我们说我有一些Polygon课程(我不会为了简洁而做任何健全检查):

基类 - > Polygon

public abstract class Polygon {
    private final int height;
    private final int width;        

    public Polygon (int h, int w) {
        height = h;
        width = w;
    }

    public int perimeter () {
        return (height + width) * 2;
    }
}

儿童类 - > Square

public class Square {
    public Square (int s) {
        super(s, s); 
}

儿童类 - > Rectangle

public class Rectangle {
    public Rectangle (int h, int w) {
        super(h, w);
    }
}

现在,如果有一个ArrayList或任何其他数据结构:

ArrayList<Polygon> m_arrList = new ArrayList<>();

然后我在ArrayList中放了一些多边形,没有任何顺序。如果我现在要对它进行排序怎么办,但取决于一些参数会有所不同:

  1. 使用不同类型的排序(合并,冒泡等)。

    如何创建一个sort (ArrayList<Polygon> al, some argument)方法,根据第二个参数对数组进行排序?我可以使用一些硬编码的值,但这并不能吸引我。

  2. 按照高度或宽度对多边形进行排序

    同样,一个方法,将ArrayList作为参数,另一个参数指定排序条件。我也可以在这里使用硬编码值,但同样不那么吸引人。

  3. 我试图在类改变的情况下避免使用硬编码的值,即它们现在包含颜色,价格等。如果我想根据其他属性(如价格)对它们进行排序,我会&#d; d必须潜入代码并手动更改所有内容。在我看来,这不是一个好习惯。

    我是否过度复杂(?)这个?我今天早上读了一些关于比较器的内容,我现在只是抓住这个概念,它们在这里有用吗?我之前不认为我使用过界面,但我愿意读一些关于它们的内容,如果这是解决方案的一部分。

5 个答案:

答案 0 :(得分:6)

该方法已存在。 List.sort(Comparator)例如

m_arrList.sort(Comparator.comparingDouble(Polygon::getWidth);

甚至。

m_arrList.sort(Comparator.comparingDouble(Polygon::getHeight);

您也可以编写自己的比较器。

m_arrList.sort((a,b)->Double.compare(a.getWidth(), b.getWidth()));

如果您需要使用自己的算法,那么您可以将比较器作为参数。

public <T> void someSortOfSort(List<T> polygons, Comparator<T> comparator){
    //Then for comparing elements.
    T a = ...
    T b = ...
    int r = comparator.compare(a,b);
    if(r>0){

    } else if( r<0){

    } else{
       //they're equal
    }
}

答案 1 :(得分:1)

Java 8 Functional Interface已经预定义了对诸如ArrayList之类的集合应用排序的工具。作为@matt提供的解决方案。但是对于更强大的功能,您可以选择将ArrayList转换为流,然后依次应用过滤参数来对ArrayList进行排序。

考虑这个例子。

List<Polygon> processed_list = 
m_array_list
           .Stream()
           .filter(s -> s > 250.62)
           .sort(Comparator.comparingDouble(Polygon::getWidth))
           .Collectors.toList();

答案 2 :(得分:0)

排序类型示例: 使用可能的排序选项声明enum SortType。为每个枚举值实现排序方法。然后添加接受数组和此枚举的sort方法:

enum SortType
{
    SQUARE {
        @Override
        public Comparator<Object> getComparator() {
            return new Comparator<Object>() {

                @Override
                public int compare(Object o1, Object o2) {
                    // Implement your sorting type. Not applicable for sorting algorythmss
                    return 0;
                }
            };
        }
    },
     WEIGHT {
        @Override
        public Comparator<Object> getComparator() {
            // TODO Auto-generated method stub
            return null;
        }
    };

    public abstract Comparator<Object> getComparator();
}

排序方法:

public void sort(List<Object> list, SortType sortType)
{
    Collections.sort(list, sortType.getComparator());
}

注意:在通用

中使用Polygon类型而不是Object类型

另请注意,类似的方法可用于实现不同的排序算法。

答案 3 :(得分:0)

替代Matts回答你可以使用枚举的力量来添加sintax糖......

考虑这个例子,一个类

class Point {
    private int x;
    private String name;

    public Point(int x, String name) {
        this.x = x;
        this.name = name;
    }
}

然后是一个可以比较点的枚举:

enum ComparatorCriteria implements Comparator<Point> {
    BY_NAME {
        @Override
        public int compare(Point o1, Point o2) {

            return o1.getName().compareTo(o2.getName());
        }
    },
    BY_X {
        @Override
        public int compare(Point o1, Point o2) {
            return Integer.compare(o1.getX(), o2.getX());
        }
    }

}

然后执行:

  List<Point> t = new ArrayList<>();

    t.add(new Point(45, "mono"));
    t.add(new Point(1, "zoo"));
    t.add(new Point(88, "alpha"));
    t.add(new Point(32, "path"));
    System.out.println("Original list: " + t);
    Collections.sort(t, ComparatorCriteria.BY_NAME);
    System.out.println("By Name: " + t);
    Collections.sort(t, ComparatorCriteria.BY_X);
    System.out.println("By x: " + t);

您的输出可能如下所示:

  

原始列表:[Point [x = 45,name = mono],Point [x = 1,name = zoo],Point   [x = 88,name = alpha],Point [x = 32,name = path]]

     

按名称:[Point [x = 88,name = alpha],Point [x = 45,name = mono],Point   [x = 32,name = path],Point [x = 1,name = zoo]]

     

按x:[Point [x = 1,name = zoo],Point [x = 32,name = path],Point [x = 45,   name = mono],Point [x = 88,name = alpha]]

答案 4 :(得分:0)

  
      
  1. 使用不同类型的排序(合并,冒泡等)。

         

    如何创建一个sort (ArrayList<Polygon> al, some argument)方法,根据第二个参数对数组进行排序?我可以使用一些硬编码的值,但这并不是为了吸引我。

  2.   

为您的排序算法创建接口。 那么你可以拥有与你那么多的接口实现。

但是:整个排序逻辑将在该接口实现中实现,您的方法sort (ArrayList<Polygon> al, SorterInterface argument)将退化为简单的委派:

public void sort (ArrayList<Polygon> al, SorterInterface sorter){
  sorter.sort(this);
}

我不认为这是有用的,并删除此sort方法,以支持SorterInterface实现之一。

  
      
  1. 按照高度或宽度对多边形进行排序

         

    同样,一个方法,将ArrayList作为参数,另一个参数指定排序条件。我也可以在这里使用硬编码值,但同样不那么吸引人。

  2.   

Java已经有Comparator接口用于此目的,可以作为参数传递给标准库中的几乎任何排序方法。