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

Java 如何根据其中一个参数对数据结构进行不同的排序?,java,sorting,Java,Sorting,假设我有一些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 () {

假设我有一些
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); 
}
子类->
矩形

public class Rectangle {
    public Rectangle (int h, int w) {
        super(h, w);
    }
}
现在,如果您有ArrayList或任何其他数据结构:

ArrayList<Polygon> m_arrList = new ArrayList<>();
ArrayList m_arrList=new ArrayList();
然后我在ArrayList中放入一些多边形,没有任何顺序。如果我现在要对其进行排序,但根据某些参数进行不同排序,该怎么办:

  • 使用不同类型的排序(合并、气泡等)

    如何创建一个
    sort(ArrayList al,some参数)
    方法,根据第二个参数对数组进行排序?我可以使用一些硬编码的值,但这对我没有吸引力

  • 按多边形的高度或宽度对多边形进行排序

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

  • 在类发生变化的情况下,我试图避免硬编码的值,即它们现在包含颜色、价格等。如果我想根据其他属性(如价格)对它们进行排序,我必须深入代码并手动更改所有内容。在我看来,这不是一个好的做法


    我是不是把这个复杂化了?今天早上我读了一些关于Comparator的文章,我现在只是掌握了这个概念,它们在这里有用吗?我认为我以前没有使用过接口,但如果这是解决方案的一部分,我愿意阅读一些有关接口的内容。

    该方法已经存在<代码>列表.排序(比较器)eg

    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
        }
    }
    
    public void someSortOfSort(列出多边形、比较器){
    //然后进行元素比较。
    T a=。。。
    T b=。。。
    int r=比较器。比较(a,b);
    如果(r>0){
    
    }else if(r排序类型示例: 使用可能的排序选项声明一个
    enum SortType
    。为每个枚举值实现一个排序方法。然后添加接受数组和此枚举的排序方法:

    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();
    }
    
    枚举排序类型
    {
    方格{
    @凌驾
    公共比较器getComparator(){
    返回新的比较器(){
    @凌驾
    公共整数比较(对象o1、对象o2){
    //实现您的排序类型。不适用于排序算法
    返回0;
    }
    };
    }
    },
    重量{
    @凌驾
    公共比较器getComparator(){
    //TODO自动生成的方法存根
    返回null;
    }
    };
    公共抽象比较器getComparator();
    }
    
    和排序方法:

    public void sort(List<Object> list, SortType sortType)
    {
        Collections.sort(list, sortType.getComparator());
    }
    
    public void排序(列表、排序类型、排序类型)
    {
    Collections.sort(list,sortType.getComparator());
    }
    
    注意:在泛型中使用
    多边形
    类型而不是
    对象
    类型


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

    除了Matts answer,您还可以使用枚举的威力添加sintax sugar

    考虑这个例子,一个类

    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());
            }
        }
    
    }
    
    enum ComparatorCriteria实现Comparator{
    名字{
    @凌驾
    公共整数比较(点o1,点o2){
    返回o1.getName().compareTo(o2.getName());
    }
    },
    作者{
    @凌驾
    公共整数比较(点o1,点o2){
    返回整数.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);
    
    List t=newarraylist();
    t、 增加(新的点(45,“单”);
    t、 增加(新的第(1)点,“动物园”);
    t、 增加(新点(88,“α”);
    t、 添加(新点(32,“路径”);
    System.out.println(“原始列表:+t”);
    Collections.sort(t,ComparatorCriteria.BY_NAME);
    System.out.println(“按名称:+t”);
    Collections.sort(t,ComparatorCriteria.BY_X);
    System.out.println(“x:+t);
    
    您的输出可以如下所示:

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

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

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

  • 使用不同类型的排序(合并、气泡等)

    如何创建一个
    排序(ArrayList al,some argument)
    方法,根据第二个参数对数组进行排序?我可以使用一些硬编码的值,但这对我没有吸引力

  • 为排序算法创建一个接口。 然后,您可以拥有任意数量的接口实现

    但是:整个排序逻辑将在该接口实现中实现,并且您的方法
    排序(ArrayList al,SorterInterface参数)
    将退化为一个简单的委托:

    public void sort (ArrayList<Polygon> al, SorterInterface sorter){
      sorter.sort(this);
    }
    
    公共空白分拣(ArrayList al,分拣机接口分拣机){
    分拣机。分拣(本);
    }
    

    我不认为这是有用的,并且删除这个<代码>排序< /代码>方法,有利于< <代码> SorterInterface <代码>实现。

  • 按多边形的高度或宽度对多边形进行排序

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

  • Java已经有了用于此目的的
    Comparator
    接口,它几乎可以作为参数传递给st中的任何排序方法
    List<Polygon> processed_list = 
    m_array_list
               .Stream()
               .filter(s -> s > 250.62)
               .sort(Comparator.comparingDouble(Polygon::getWidth))
               .Collectors.toList();