在Java中使用Comparable实现VO的多个动态字段

sam*_*mba 7 java comparable comparator

我上课了

public class StudentVO {
   int age;
   String name;  
}
Run Code Online (Sandbox Code Playgroud)

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

是否有可能做到这一点?

NIN*_*OOP 17

1)您应该编写两个Comparator来分别对年龄和名称进行排序,然后使用Collections.sort(List,Comparator).像这样的东西:

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());
  }

}
Run Code Online (Sandbox Code Playgroud)

然后使用它们,根据以下内容进行排序age:

Collections.sort(list,new AgeComparator());
Run Code Online (Sandbox Code Playgroud)

基于以下方式排序name:

Collections.sort(list,new NameComparator());
Run Code Online (Sandbox Code Playgroud)

2)如果你认为ListStudentVO有分拣,都说排序假设一些自然顺序age.然后,使用Comparable for ageComparatorfor name.

 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());
    }

 }
Run Code Online (Sandbox Code Playgroud)

然后使用它们,根据以下内容进行排序age:

Collections.sort(list);
Run Code Online (Sandbox Code Playgroud)

基于以下方式排序name:

Collections.sort(list,new NameComparator());
Run Code Online (Sandbox Code Playgroud)


Ant*_*iuc 10

有一个在这个新的方法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'}]
Run Code Online (Sandbox Code Playgroud)

按几个字段排序:

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'}]
Run Code Online (Sandbox Code Playgroud)