如何按私人字段对列表进行排序?

我的实体类看起来像这样:

public class Student {

   private int grade;

  //other fields and methods
 }

我这样用它:

List students = ...;

我如何通过 grade学生进行排序,同时考虑到它是一个私有字段?

12
@Fanta但是在这种情况下,你确实需要属性,那么当你不想隐藏它时隐藏它的重点是什么?当然你可以编写一个使用私有变量的方法(比如答案),但是使用getter并没有什么本质上的错误。这种情况本质上是C#中的一个功能,您可以在其中使用具有公共getter和私有setter的属性。
额外 作者 Burak,
@Fanta但是在这种情况下,你确实需要属性,那么当你不想隐藏它时隐藏它的重点是什么?当然你可以编写一个使用私有变量的方法(比如答案),但是使用getter并没有什么本质上的错误。这种情况本质上是C#中的一个功能,您可以在其中使用具有公共getter和私有setter的属性。
额外 作者 Burak,
@Fanta谁告诉你getter 通常是一个不好的做法
额外 作者 Aris,
@Fanta谁告诉你getter 通常是一个不好的做法
额外 作者 Aris,
你有那个领域的吸气剂吗?
额外 作者 Eugene,
setter 可能是...但是 getter ,不知道如何
额外 作者 Eugene,
setter 可能是...但是 getter ,不知道如何
额外 作者 Eugene,
“吸毒者和制定者通常都是坏习惯。”是和否 - 他们是坏习惯在课堂上包含商业逻辑。你在这里有一个数据传输对象,只是一个数据结构需要getter getters/Setters。
额外 作者 Timothy Truckle,
“吸毒者和制定者通常都是坏习惯。”是和否 - 他们是坏习惯在课堂上包含商业逻辑。你在这里有一个数据传输对象,只是一个数据结构需要getter getters/Setters。
额外 作者 Timothy Truckle,
@Popeye getter/setter对于DTO至关重要。但是使用业务对象,它们会启用功能羡慕并违反告诉,不要问!原则。
额外 作者 Timothy Truckle,
@Popeye getter/setter对于DTO至关重要。但是使用业务对象,它们会启用功能羡慕并违反告诉,不要问!原则。
额外 作者 Timothy Truckle,
从什么时候开始使用 getters 成为不好的做法?从未进行过10年的Java开发+之前从未听过这样的声明
额外 作者 Popeye,
从什么时候开始使用 getters 成为不好的做法?从未进行过10年的Java开发+之前从未听过这样的声明
额外 作者 Popeye,
我不会把吸气剂称为“坏”做法,但它们大多没用,因为它们不是一个有约束力的合同而不是没有吸气剂的暴露场。遗憾的是,IDE通常会主动惩罚您不使用这种冗余构造(例如,自动重构通常只检查getter而不是直接检查字段)。绝大多数权威人士所谓的“优势”主要是妄想。
额外 作者 Erwin Smout,
我不会把吸气剂称为“坏”做法,但它们大多没用,因为它们不是一个有约束力的合同而不是没有吸气剂的暴露场。遗憾的是,IDE通常会主动惩罚您不使用这种冗余构造(例如,自动重构通常只检查getter而不是直接检查字段)。绝大多数权威人士所谓的“优势”主要是妄想。
额外 作者 Erwin Smout,
@PallavKabra我认为你是那个必须阅读它的人。声明私有变量以便您可以封装数据然后使用getter就像将事物隐藏在一个玻璃盒中。该字段不是公共的,但获取它的方法是,所以你实际上打破了封装概念。
额外 作者 Fanta,
@PallavKabra我认为你是那个必须阅读它的人。声明私有变量以便您可以封装数据然后使用getter就像将事物隐藏在一个玻璃盒中。该字段不是公共的,但获取它的方法是,所以你实际上打破了封装概念。
额外 作者 Fanta,
我真的不想使用它们,因为它们通常是一种不好的做法。
额外 作者 Fanta,
我真的不想使用它们,因为它们通常是一种不好的做法。
额外 作者 Fanta,
@Fanta阅读有关封装的内容
额外 作者 Pallav Kabra,
@Fanta阅读有关封装的内容
额外 作者 Pallav Kabra,

18 答案

你有这些选择:

  1. make grade visible
  2. define a getter method for grade
  3. define a Comparator inside Student
  4. make Student implement Comparable
  5. use reflection (in my opinion this is not a solution, it is a workaround/hack)

解决方案 3 的示例:

public class Student {
    private int grade;

    public static Comparator byGrade = Comparator.comparing(s -> s.grade);
}

并像这样使用它:

List students = Arrays.asList(student2, student3, student1);
students.sort(Student.byGrade);
System.out.println(students);

这是我最喜欢的解决方案因为:

  • 您可以轻松定义多个 Comparator s
  • 代码不多
  • 您的字段保持私密且已封装

解决方案示例 4

public class Student implements Comparable {
    private int grade;

    @Override
    public int compareTo(Object other) {
        if (other instanceof Student) {
            return Integer.compare(this.grade, ((Student) other).grade);
        }
        return -1;
    }
}

您可以像这样排序无处不在

List students = Arrays.asList(student2, student3, student1);
Collections.sort(students);
System.out.println(students);
33
额外
@ user1708042一个错误 - 它可能是一个内部类,但最好使用tge java-8表示法。我更新了我的回答,谢谢!
额外 作者 slartidan,
@Evertude我的示例代码中已经是 public
额外 作者 slartidan,
“可比较是一个好主意!”也许,也许不是......这将决定学生的“自然顺序”。有人可能会说学生成绩不能很好... ; O)
额外 作者 Timothy Truckle,
您甚至可以实现 Comparable 接口
额外 作者 MaanooAk,
我最喜欢的是选项3 - 在Student中定义一个Comparator。
额外 作者 Eddy Young,
我喜欢解决方案3:功能代码的一个聪明的例子。但为什么你称之为“定义内部阶级”?
额外 作者 user1708042,
您的byGrade Comparator必须是公开的,否则您将无法使用它。请调整你的答案。
额外 作者 Evertude,

你有这些选择:

  1. make grade visible
  2. define a getter method for grade
  3. define a Comparator inside Student
  4. make Student implement Comparable
  5. use reflection (in my opinion this is not a solution, it is a workaround/hack)

解决方案 3 的示例:

public class Student {
    private int grade;

    public static Comparator byGrade = Comparator.comparing(s -> s.grade);
}

并像这样使用它:

List students = Arrays.asList(student2, student3, student1);
students.sort(Student.byGrade);
System.out.println(students);

这是我最喜欢的解决方案因为:

  • 您可以轻松定义多个 Comparator s
  • 代码不多
  • 您的字段保持私密且已封装

解决方案示例 4

public class Student implements Comparable {
    private int grade;

    @Override
    public int compareTo(Object other) {
        if (other instanceof Student) {
            return Integer.compare(this.grade, ((Student) other).grade);
        }
        return -1;
    }
}

您可以像这样排序无处不在

List students = Arrays.asList(student2, student3, student1);
Collections.sort(students);
System.out.println(students);
33
额外
@ user1708042一个错误 - 它可能是一个内部类,但最好使用tge java-8表示法。我更新了我的回答,谢谢!
额外 作者 slartidan,
@Evertude我的示例代码中已经是 public
额外 作者 slartidan,
“可比较是一个好主意!”也许,也许不是......这将决定学生的“自然顺序”。有人可能会说学生成绩不能很好... ; O)
额外 作者 Timothy Truckle,
您甚至可以实现 Comparable 接口
额外 作者 MaanooAk,
我最喜欢的是选项3 - 在Student中定义一个Comparator。
额外 作者 Eddy Young,
我喜欢解决方案3:功能代码的一个聪明的例子。但为什么你称之为“定义内部阶级”?
额外 作者 user1708042,
您的byGrade Comparator必须是公开的,否则您将无法使用它。请调整你的答案。
额外 作者 Evertude,

通常,如果您需要一个取决于学生成绩的行为,则必须可以访问此信息 - 添加允许其他代码访问它的方法或属性。

因此,最简单的解决方法是:

public class Student implements IStudent {

    ...
    private int grade;
    ...
   //other fields and methods

    public int getGrade() {
        return grade;
    }
}

你应该扩展接口 IStudent :)

但是,如果您只需要进行排序,则可以使用其他答案中已经提出的建议:实现 可比较 界面。这样,您可以隐藏 grade ,并在 int compareTo 方法中使用它。

5
额外
@TimothyTruckle我不确定你在说什么。从DDD的角度来看,这些都是完全不同的世界。具有吸气剂或固定剂的DTO仅依赖于您的工具/基础设施 - 如果从技术角度不需要它们,则不要添加它们。对于实体,您只需尝试创建一个合理的对象模型,其中包含getter/setter,从商业角度来看它们是有意义的。
额外 作者 BartoszKP,
@TimothyTruckle为什么一个实体会出错呢?
额外 作者 BartoszKP,
@TimothyTruckle这是一个很好的观点。
额外 作者 BartoszKP,
“为什么不自己给DTO留下答案呢?”我给OP留了一个评论,猜测我的答案无论如何都会流失......
额外 作者 Timothy Truckle,
“为什么这对于一个实体来说是错误的” - 恕我直言实体仍然是某种(增强的?)DTO。
额外 作者 Timothy Truckle,
“实施可比较的界面”这将确定学生的“自然顺序”。有人可能会说学生的成绩不能成为一个好的...; o)
额外 作者 Timothy Truckle,
只要我们谈论DTO,你的答案就很好......
额外 作者 Timothy Truckle,
“从DDD的角度来看,这些是完全不同的世界[...]只有你的工具/基础设施”同意,只是说getter和Setter不属于业务逻辑
额外 作者 Timothy Truckle,
@TimothyTruckle为什么不自己回答一下DTO的答案? +1
额外 作者 Popeye,

通常,如果您需要一个取决于学生成绩的行为,则必须可以访问此信息 - 添加允许其他代码访问它的方法或属性。

因此,最简单的解决方法是:

public class Student implements IStudent {

    ...
    private int grade;
    ...
   //other fields and methods

    public int getGrade() {
        return grade;
    }
}

你应该扩展接口 IStudent :)

但是,如果您只需要进行排序,则可以使用其他答案中已经提出的建议:实现 可比较 界面。这样,您可以隐藏 grade ,并在 int compareTo 方法中使用它。

5
额外
@TimothyTruckle我不确定你在说什么。从DDD的角度来看,这些都是完全不同的世界。具有吸气剂或固定剂的DTO仅依赖于您的工具/基础设施 - 如果从技术角度不需要它们,则不要添加它们。对于实体,您只需尝试创建一个合理的对象模型,其中包含getter/setter,从商业角度来看它们是有意义的。
额外 作者 BartoszKP,
@TimothyTruckle为什么一个实体会出错呢?
额外 作者 BartoszKP,
@TimothyTruckle这是一个很好的观点。
额外 作者 BartoszKP,
只要我们谈论DTO,你的答案就很好......
额外 作者 Timothy Truckle,
“实施可比较的界面”这将确定学生的“自然顺序”。有人可能会说学生的成绩不能成为一个好的...; o)
额外 作者 Timothy Truckle,
“为什么不自己给DTO留下答案呢?”我给OP留了一个评论,猜测我的答案无论如何都会流失......
额外 作者 Timothy Truckle,
“为什么这对于一个实体来说是错误的” - 恕我直言实体仍然是某种(增强的?)DTO。
额外 作者 Timothy Truckle,
“从DDD的角度来看,这些是完全不同的世界[...]只有你的工具/基础设施”同意,只是说getter和Setter不属于业务逻辑
额外 作者 Timothy Truckle,
@TimothyTruckle为什么不自己回答一下DTO的答案? +1
额外 作者 Popeye,

您的类可以实现 Comparable 接口。然后,您可以轻松地对列表进行排序:

public class Student implements IStudent, Comparable
{
  ...

  private int grade;
  ...

  @Override
  public int compareTo(Student other)
  {
    return (grade - other.grade);
  }

}

public class Section
{
  private List studentsList;

  ...

  public void sortStudents()
  {
    studentsList.sort(null);
  }

}
3
额外

您的类可以实现 Comparable 接口。然后,您可以轻松地对列表进行排序:

public class Student implements IStudent, Comparable
{
  ...

  private int grade;
  ...

  @Override
  public int compareTo(Student other)
  {
    return (grade - other.grade);
  }

}

public class Section
{
  private List studentsList;

  ...

  public void sortStudents()
  {
    studentsList.sort(null);
  }

}
3
额外

如果您确实需要按字段排序,则无法访问您可以使用反射

private static int extractGrade(Student student) {
    try {
        Field field = Student.class.getDeclaredField("grade");
        field.setAccessible(true);
        return field.getInt(student);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public static void main(String[] args) {
    Comparator studentComparator = Comparator.comparingInt(DemoApplication::extractGrade);
    List students = Arrays.asList(new Student(1), new Student(10), new Student(5));
    students.sort(studentComparator);
}

但我不得不说这种方法有点不安全。

除非绝对必要,否则不要使用它。例如,最好使用getter方法访问给定字段。

如果您在模块路径上针对Java 9+运行此代码,您可能会遇到问题(您可以抛出 InaccessibleObjectException )。

About implementing Comparable

来自可比较的 docs

此接口对实现它的每个类的对象强加一个总排序。这种排序被称为类的自然排序,而类的{@code compareTo}方法被称为自然比较方法

Student自然排序可能是什么? 名字?姓?他们的组合?

对于数字来说,这个问题很容易回答,但对于像 Student 这样的类则不行。

所以我不认为 Student 应该是 Comparable ,它们是人类而不是日期或数字。你不能说谁更伟大,谁是平等的谁更少。

3
额外
我相信当你想通过我确定的特征如同等级来排序任何类别时,在这个例子中,它成为一个可比较的候选人。关键是在对象中存在多种类型的排序。在这种情况下,没有一个排序将是自然并且我不会使用这个表面 - 在这种情况下,我在实现比较功能的类中有一个Comparator字段。
额外 作者 jhonata.sobrinho,

如果您确实需要按字段排序,则无法访问您可以使用反射

private static int extractGrade(Student student) {
    try {
        Field field = Student.class.getDeclaredField("grade");
        field.setAccessible(true);
        return field.getInt(student);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public static void main(String[] args) {
    Comparator studentComparator = Comparator.comparingInt(DemoApplication::extractGrade);
    List students = Arrays.asList(new Student(1), new Student(10), new Student(5));
    students.sort(studentComparator);
}

但我不得不说这种方法有点不安全。

除非绝对必要,否则不要使用它。例如,最好使用getter方法访问给定字段。

如果您在模块路径上针对Java 9+运行此代码,您可能会遇到问题(您可以抛出 InaccessibleObjectException )。

About implementing Comparable

来自可比较的 docs

此接口对实现它的每个类的对象强加一个总排序。这种排序被称为类的自然排序,而类的{@code compareTo}方法被称为自然比较方法

Student自然排序可能是什么? 名字?姓?他们的组合?

对于数字来说,这个问题很容易回答,但对于像 Student 这样的类则不行。

所以我不认为 Student 应该是 Comparable ,它们是人类而不是日期或数字。你不能说谁更伟大,谁是平等的谁更少。

3
额外
我相信当你想通过我确定的特征如同等级来排序任何类别时,在这个例子中,它成为一个可比较的候选人。关键是在对象中存在多种类型的排序。在这种情况下,没有一个排序将是自然并且我不会使用这个表面 - 在这种情况下,我在实现比较功能的类中有一个Comparator字段。
额外 作者 jhonata.sobrinho,

为Student课程实施可比较界面实现方法 int compareTo(T o)。这样您就可以将成绩属性保密。

3
额外

JDK 1.8提供的选项是使用 streamsorted()方法,该方法不需要实现 Comparable 接口。 您需要为字段 grade 实现accessor(getter)方法

public class Student {

private int grade;

public int getGrade() {
    return grade;
}

public Student setGrade(int grade) {
    this.grade = grade;
    return this;
}}

然后给出unsortedStudentList你可以像下面的代码一样对它进行排序:

List sortedStudentList = unsortedStudentList
             .stream()
             .sorted(Comparator.comparing(Student::getGrade))
             .collect(Collectors.toList());

此外, sorted()方法还允许您根据其他字段(如果有)对学生进行排序。例如,考虑学生的字段 name ,在这种情况下,您希望根据年级和名称对studentList进行排序。所以 Student 类是这样的:

public class Student {

private int grade;
private String name;

public int getGrade() {
    return grade;
}

public Student setGrade(int grade) {
    this.grade = grade;
    return this;
}

public String getName() {
    return name;
}

public Student setName(String name) {
    this.name = name;
    return this;
}} 

要根据这两个字段进行排序:

 List sortedStudentList = unsortedStudentList
              .stream()
              .sorted(Comparator.comparing(Student::getGrade)
              .thenComparing(Comparator.comparing(Student::getName)))
              .collect(Collectors.toList());

当第一个比较器比较两个相等的物体时,第二个比较器发挥作用。

3
额外

JDK 1.8提供的选项是使用 streamsorted()方法,该方法不需要实现 Comparable 接口。 您需要为字段 grade 实现accessor(getter)方法

public class Student {

private int grade;

public int getGrade() {
    return grade;
}

public Student setGrade(int grade) {
    this.grade = grade;
    return this;
}}

然后给出unsortedStudentList你可以像下面的代码一样对它进行排序:

List sortedStudentList = unsortedStudentList
             .stream()
             .sorted(Comparator.comparing(Student::getGrade))
             .collect(Collectors.toList());

此外, sorted()方法还允许您根据其他字段(如果有)对学生进行排序。例如,考虑学生的字段 name ,在这种情况下,您希望根据年级和名称对studentList进行排序。所以 Student 类是这样的:

public class Student {

private int grade;
private String name;

public int getGrade() {
    return grade;
}

public Student setGrade(int grade) {
    this.grade = grade;
    return this;
}

public String getName() {
    return name;
}

public Student setName(String name) {
    this.name = name;
    return this;
}} 

要根据这两个字段进行排序:

 List sortedStudentList = unsortedStudentList
              .stream()
              .sorted(Comparator.comparing(Student::getGrade)
              .thenComparing(Comparator.comparing(Student::getName)))
              .collect(Collectors.toList());

当第一个比较器比较两个相等的物体时,第二个比较器发挥作用。

3
额外

之前提到但未作为示例显示的另一个选项是实现一个特殊的 Comparator ,用于按等级进行比较。

此示例包含一个实现接口 IStudent 的类 Student ,一个 StudentGradeComparator 和一个使用示例的小类 Main 数据。

进一步说明作为代码注释,请阅读

/**
 * A class that compares students by their grades.
 */
public class StudentGradeComparator implements Comparator {

    @Override
    public int compare(IStudent studentOne, IStudent studentTwo) {
        int result;
        int studentOneGrade = studentOne.getGrade();
        int studentTwoGrade = studentTwo.getGrade();

        /* The comparison just decides if studentOne will be placed
         * in front of studentTwo in the sorted order or behind
         * or if they have the same comparison value and are considered equal
         */
        if (studentOneGrade > studentTwoGrade) {
            /* larger grade is considered "worse", 
             * thus, the comparison puts studentOne behind studentTwo
             */
            result = 1;
        } else if (studentOneGrade < studentTwoGrade) {
            /* smaller grade is considered "better"
             * thus, the comparison puts studentOne in front of studentTwo
             */
            result = -1;
        } else {
            /* the students have equal grades,
             * thus, there will be no swap 
             */
            result = 0;
        }

        return result;
    }
}

You can apply this class in the sort(Comparator<? super IStudent> comparator) method of a List:

/**
 * The main class for trying out the sorting by Comparator
 */
public class Main {

    public static void main(String[] args) {
       //a test list for students
        List students = new ArrayList();

       //create some example students
        IStudent beverly = new Student("Beverly", 3);
        IStudent miles = new Student("Miles", 2);
        IStudent william = new Student("William", 4);
        IStudent deanna = new Student("Deanna", 1);
        IStudent jeanLuc = new Student("Jean-Luc", 1);
        IStudent geordi = new Student("Geordi", 5);

       //add the example students to the list
        students.add(beverly);
        students.add(miles);
        students.add(william);
        students.add(deanna);
        students.add(jeanLuc);
        students.add(geordi);

       //print the list in an unordered state first
        System.out.println("———— BEFORE SORTING ————");
        students.forEach((IStudent student) -> {
            System.out.println(student.getName() + ": " + student.getGrade());
        });

        /*---------------------------------------*
         * THIS IS HOW YOU APPLY THE COMPARATOR  *
         *---------------------------------------*/
        students.sort(new StudentGradeComparator());

       //print the list ordered by grade
        System.out.println("———— AFTER SORTING ————");
        students.forEach((IStudent student) -> {
            System.out.println(student.getName() + ": " + student.getGrade());
        });
    }
}

为了完整起见,这里是接口 IStudent 及其实现类 Student

public interface IStudent {

    String getName();
    int getGrade();

}


/**
 * A class representing a student
 */
public class Student implements IStudent {

    private String name;
    private int grade;

    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

}
2
额外

之前提到但未作为示例显示的另一个选项是实现一个特殊的 Comparator ,用于按等级进行比较。

此示例包含一个实现接口 IStudent 的类 Student ,一个 StudentGradeComparator 和一个使用示例的小类 Main 数据。

进一步说明作为代码注释,请阅读

/**
 * A class that compares students by their grades.
 */
public class StudentGradeComparator implements Comparator {

    @Override
    public int compare(IStudent studentOne, IStudent studentTwo) {
        int result;
        int studentOneGrade = studentOne.getGrade();
        int studentTwoGrade = studentTwo.getGrade();

        /* The comparison just decides if studentOne will be placed
         * in front of studentTwo in the sorted order or behind
         * or if they have the same comparison value and are considered equal
         */
        if (studentOneGrade > studentTwoGrade) {
            /* larger grade is considered "worse", 
             * thus, the comparison puts studentOne behind studentTwo
             */
            result = 1;
        } else if (studentOneGrade < studentTwoGrade) {
            /* smaller grade is considered "better"
             * thus, the comparison puts studentOne in front of studentTwo
             */
            result = -1;
        } else {
            /* the students have equal grades,
             * thus, there will be no swap 
             */
            result = 0;
        }

        return result;
    }
}

You can apply this class in the sort(Comparator<? super IStudent> comparator) method of a List:

/**
 * The main class for trying out the sorting by Comparator
 */
public class Main {

    public static void main(String[] args) {
       //a test list for students
        List students = new ArrayList();

       //create some example students
        IStudent beverly = new Student("Beverly", 3);
        IStudent miles = new Student("Miles", 2);
        IStudent william = new Student("William", 4);
        IStudent deanna = new Student("Deanna", 1);
        IStudent jeanLuc = new Student("Jean-Luc", 1);
        IStudent geordi = new Student("Geordi", 5);

       //add the example students to the list
        students.add(beverly);
        students.add(miles);
        students.add(william);
        students.add(deanna);
        students.add(jeanLuc);
        students.add(geordi);

       //print the list in an unordered state first
        System.out.println("———— BEFORE SORTING ————");
        students.forEach((IStudent student) -> {
            System.out.println(student.getName() + ": " + student.getGrade());
        });

        /*---------------------------------------*
         * THIS IS HOW YOU APPLY THE COMPARATOR  *
         *---------------------------------------*/
        students.sort(new StudentGradeComparator());

       //print the list ordered by grade
        System.out.println("———— AFTER SORTING ————");
        students.forEach((IStudent student) -> {
            System.out.println(student.getName() + ": " + student.getGrade());
        });
    }
}

为了完整起见,这里是接口 IStudent 及其实现类 Student

public interface IStudent {

    String getName();
    int getGrade();

}


/**
 * A class representing a student
 */
public class Student implements IStudent {

    private String name;
    private int grade;

    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

}
2
额外

当你想保持毕业时,你可以这样做:

students = students.stream().sorted((s1, s2) -> {
        try {
            Field f = s1.getClass().getDeclaredField("grade");
            f.setAccessible(true);
            int i = ((Integer)f.getInt(s1)).compareTo((Integer) f.get(s2));
            f.setAccessible(false);
            return i;
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }
        return 0;
    }).collect(Collectors.toList());
1
额外

当你想保持毕业时,你可以这样做:

students = students.stream().sorted((s1, s2) -> {
        try {
            Field f = s1.getClass().getDeclaredField("grade");
            f.setAccessible(true);
            int i = ((Integer)f.getInt(s1)).compareTo((Integer) f.get(s2));
            f.setAccessible(false);
            return i;
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }
        return 0;
    }).collect(Collectors.toList());
1
额外

吸气剂并不是一种糟糕的做法,它们完全针对您的问题:访问私人领域以阅读它们 添加一个getter,你可以这样做:

studentsList.stream().sorted((s1, s2) -> s1.getGrade()compareTo(s2.getGrade)).collect(Collectors.toList())  

更新:如果您确实希望将等级保持为私有,则需要实现 Comparable 并覆盖compare-method。

1
额外

我相信这里最好的选择是创建一个 Comparator ,其中需要排序列表,因为您可能需要按其他地方的其他字段排序,这会使您的域类膨胀:

List sorted = list.stream()
    .sorted(Comparator.comparingInt(o -> o.grade))
    .collect(Collectors.toList());
1
额外

我相信这里最好的选择是创建一个 Comparator ,其中需要排序列表,因为您可能需要按其他地方的其他字段排序,这会使您的域类膨胀:

List sorted = list.stream()
    .sorted(Comparator.comparingInt(o -> o.grade))
    .collect(Collectors.toList());
1
额外