使用可比在Java VO的多个动态领域(Using Comparable for multiple

2019-09-01 02:35发布

我有一个类

public class StudentVO {
   int age;
   String name;  
}

我用同样的类在两个不同的领域。 在一个地方,我需要根据年龄进行排序。 在另一个地方,我需要根据名称和在另一个地方我可能需要根据年龄和名字排序排序。 我怎样才能做到这一点? 如果一个字段我可以覆盖compareTo()

是否有可能做到这一点?

Answer 1:

1)你应该写两个比较器的单独年龄和姓名排序,然后用Collections.sort(名单,比较) 。 事情是这样的:

class StudentVO {
  private String name;
  private int age;
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  public int getAge() {
      return age;
  }
  public void setAge(int age) {
      this.age = age;
  }
}

class AgeComparator implements Comparator<StudentVO> {

@Override
public int compare(StudentVO o1, StudentVO o2) {
    Integer age1 = o1.getAge();
    Integer age2 = o2.getAge();
    return age1.compareTo(age2);
  }

}

class NameComparator implements Comparator<StudentVO> {

  @Override
  public int compare(StudentVO o1, StudentVO o2) {
      return o1.getName().compareTo(o2.getName());
  }

}

然后用它们,要根据排序age

Collections.sort(list,new AgeComparator());

基于排序name

Collections.sort(list,new NameComparator());

2)如果您认为该ListStudentVO有整理的一些自然顺序,通过说假设排序age 。 然后,使用可比的ageComparatorname

 class StudentVO implements Comparable<StudentVO>{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public int compareTo(StudentVO o) {
        return ((Integer)getAge()).compareTo(o.getAge());
    }
}

class NameComparator implements Comparator<StudentVO> {

    @Override
    public int compare(StudentVO o1, StudentVO o2) {
        return o1.getName().compareTo(o2.getName());
    }

 }

然后用它们,要根据排序age

Collections.sort(list);

基于排序name

Collections.sort(list,new NameComparator());


Answer 2:

有一个在这个新方法java-8看比较#对比和比较#thenComparing 。 所有你需要的是提供LAMDA表达式/法参考要么Stream#sorted()List#sort()方法。

例如排序由一个场:

List<StudentVO> students = Arrays.asList(
        new StudentVO(20,"Bob"),
        new StudentVO(19, "Jane")
);
// sort by age
students.stream()
        .sorted(Comparator.comparing(StudentVO::getAge))
        .forEach(System.out::println);
// [StudentVO{age=19, name='Jane'},StudentVO{age=20, name='Bob'}]
// sort by name
students.stream()
        .sorted(Comparator.comparing(StudentVO::getName))
        .forEach(System.out::println);
// [StudentVO{age=20, name='Bob'}, StudentVO{age=19, name='Jane'}]

通过几个字段排序:

List<StudentVO> students = Arrays.asList(
        new StudentVO(20,"Bob"),
        new StudentVO(19, "Jane"),
        new StudentVO(21,"Bob")
);
// by age and then by name
students.stream()
        .sorted(Comparator
                .comparing(StudentVO::getAge)
                .thenComparing(StudentVO::getName)
        ).forEach(System.out::println);
// [StudentVO{age=19, name='Jane'}, StudentVO{age=20, name='Bob'}, StudentVO{age=21, name='Bob'}]
// by name an then by age
students.stream()
        .sorted(Comparator
                .comparing(StudentVO::getName)
                .thenComparing(StudentVO::getAge)
        ).forEach(System.out::println);
// [StudentVO{age=20, name='Bob'}, StudentVO{age=21, name='Bob'}, StudentVO{age=19, name='Jane'}]


Answer 3:

以下是代码片段:

public class StudentNameComparator implements Comparator<StudentVO>{

@Override
public int compare(StudentVO s1, StudentVO s2) {

        //ascending order
        return s1.getName().compareTo(s2.getName());

        //descending order
        //return s2.getName().compareTo(s1.getName());
       }
}

根据你的问题,这也将工作时的指定字段的值会发生变化。 你只需要记住调用sort方法与此比较。



Answer 4:

在Java中,必须比较对象的两个主要途径。 首先是类本身来实现可比的接口,这将意味着只有一个实现。 二是具有类实现比较接口。 通过这种方式,你可以有相同的类多个比较。

这意味着,你可以定义你的StudentVo类为例3 diffenrent比较:一种是仅在名称相比,另一种比较年龄和这两个属性是最后一个。

在您的应用程序,您使用适合您需要根据您要比较的实施。 在一个地方,你会比较年龄Collections.sort学生(myStudents,新CompareStudentOnAge())。 在另一个地方,你用另一种实现方式。

你可以在这个博客帖子一些解释: http://javarevisited.blogspot.fr/2011/06/comparator-and-comparable-in-java.html



Answer 5:

我最近不得不解决这个问题了。 不知道这是完全一样的情况下是你的,但我不得不写一个内存中排序为一个网格,handwaving在OOM条件等的零个或多个列,因为我的问题的范围非常有限。

我写了一个比较的每一列,要花比较列表的比较。 当我确定了所需的列进行排序,并按照什么顺序,我添加了相应的比较器的实例来比较的列表。 然后,使用链接的比较来执行实际的排序。

public class MyObject
{
    private String name;
    private int age;
    private Date registered;
}

所以,像这样每个比较:

public class NameComparator
    implements Comparator<MyObject>
{
    public int compare(MyObject o1, MyObject o2)
    {
        return o1.getName().compareTo(o2.getName);
    }
}

这对于链比较:

public class ChainedComparator
    implements Comparator<MyObject>
{
    public int compare(MyObject o1, MyObject o2) {
        for(Comparator<MyObject> comparator : comparators) {
            int result = comparator.compare(o1,o2);
            if(result != 0) {
                return result;
            }
        }
        return 0;
    }
}
    private List<Comparator<MyObject>> comparators = new ArrayList<>();
}

留给你的想象力被解析排序和构建链比较。 事实上,我提出这一点更为复杂,因为我也纳入其中我实现通过根据需要在链比较交换参数的顺序在调用子比较器的方向。



文章来源: Using Comparable for multiple dynamic fields of VO in java