Java 使用1.8 jdk按多个字段对对象列表进行排序

Java 使用1.8 jdk按多个字段对对象列表进行排序,java,sorting,comparator,Java,Sorting,Comparator,我收集了一些人: class Person { public String name; public int count; public boolean favorite; // getters / setters ... } 我想按以下方式对人员集合进行排序: 第一次显示收藏夹为true的项目 第二次显示计数>0的项目 上次显示计数=0的项目 如何使用Comparator from 1.8 JDK编写此条件并检索预期结果?假设您希望对人员进行排序而不是筛选,

我收集了一些人:

class Person {
    public String name;
    public int count;
    public boolean favorite;

    // getters / setters ...
}
我想按以下方式对人员集合进行排序:

  • 第一次显示收藏夹为true的项目
  • 第二次显示计数>0的项目
  • 上次显示计数=0的项目

  • 如何使用Comparator from 1.8 JDK编写此条件并检索预期结果?

    假设您希望对人员进行排序而不是筛选,可以执行以下操作:

    class Person implements Comparable<Person>
    {
      ...
    
      @Override
      int compareTo(Person person)
      {
        // Maye not specified
        if (person == null)
          return (1);
    
        // Compare 'favorite'
        // Favorites first, so flag=true means smaller
        if (this.favorite && (!person.favorite))
          return (-1);
        else if ((!this.favorite) && person.favorite)
          return (1);
    
        // Compare 'count'
        // Having count > 0 first, so count=0 means greater
        // Assuming count is never negative
        if ((this.count == 0) && (person.count > 0))
          return (1);
        if ((this.count > 0) && (person.count == 0))
          return (-1);
    
        // At this point, both persons have the same 'favorite' flag
        // And both have either count=0 or count>0
        // Order by name in that case
        return (this.name.compareTo(person.name));
    
      } // compareTo
    
    } // class Person
    
    class-Person实现可比性
    {
    ...
    @凌驾
    国际比较(个人)
    {
    //可能未指定
    if(person==null)
    申报表(1);
    //比较“最爱”
    //首先是收藏夹,因此flag=true意味着更小
    if(this.favorite&(!person.favorite))
    返回(-1);
    如果(!this.favorite)和&person.favorite),则为else
    申报表(1);
    //比较“计数”
    //先让count>0,所以count=0意味着更大
    //假设计数从不为负
    如果((this.count==0)和&(person.count>0))
    申报表(1);
    如果((this.count>0)和&(person.count==0))
    返回(-1);
    //此时,两个人都有相同的“收藏”标志
    //两者都有count=0或count>0
    //在那种情况下,按姓名排序
    return(this.name.compareTo(person.name));
    }//比较
    }//班主任
    
    之后,对您的人员进行分类:

    List<Person> my_persons;
    my_persons = ....
    Collections.sort(my_persons);
    
    列出我的人;
    我的人=。。。。
    集合。排序(我的人);
    
    假设您希望对人员进行排序而不是筛选,您可以执行以下操作:

    class Person implements Comparable<Person>
    {
      ...
    
      @Override
      int compareTo(Person person)
      {
        // Maye not specified
        if (person == null)
          return (1);
    
        // Compare 'favorite'
        // Favorites first, so flag=true means smaller
        if (this.favorite && (!person.favorite))
          return (-1);
        else if ((!this.favorite) && person.favorite)
          return (1);
    
        // Compare 'count'
        // Having count > 0 first, so count=0 means greater
        // Assuming count is never negative
        if ((this.count == 0) && (person.count > 0))
          return (1);
        if ((this.count > 0) && (person.count == 0))
          return (-1);
    
        // At this point, both persons have the same 'favorite' flag
        // And both have either count=0 or count>0
        // Order by name in that case
        return (this.name.compareTo(person.name));
    
      } // compareTo
    
    } // class Person
    
    class-Person实现可比性
    {
    ...
    @凌驾
    国际比较(个人)
    {
    //可能未指定
    if(person==null)
    申报表(1);
    //比较“最爱”
    //首先是收藏夹,因此flag=true意味着更小
    if(this.favorite&(!person.favorite))
    返回(-1);
    如果(!this.favorite)和&person.favorite),则为else
    申报表(1);
    //比较“计数”
    //先让count>0,所以count=0意味着更大
    //假设计数从不为负
    如果((this.count==0)和&(person.count>0))
    申报表(1);
    如果((this.count>0)和&(person.count==0))
    返回(-1);
    //此时,两个人都有相同的“收藏”标志
    //两者都有count=0或count>0
    //在那种情况下,按姓名排序
    return(this.name.compareTo(person.name));
    }//比较
    }//班主任
    
    之后,对您的人员进行分类:

    List<Person> my_persons;
    my_persons = ....
    Collections.sort(my_persons);
    
    列出我的人;
    我的人=。。。。
    集合。排序(我的人);
    
    您可以使用
    比较器。比较(…)。然后比较(…)
    按多个属性排序。对于首先排序收藏夹,您可以按该属性排序,但随后必须反转结果,因为
    false
    true
    之前排序。假设您只想按
    计数
    是否为
    >0
    排序,而不是按计数的实际值排序:

    List<Person> persons = Arrays.asList(
            new Person("p1", 2, true),
            new Person("p2", 0, false),
            new Person("p3", 0, true),
            new Person("p4", 1, false),
            new Person("p5", 3, true));
    
    persons.stream().sorted(Comparator
                .comparing(Person::isFavorite).reversed()
                .thenComparing(p -> p.getCount() == 0))
        .forEach(System.out::println);
    
    请注意,最后的
    count==0
    条件是冗余的(假设
    count
    不能是
    <0

    或直接按
    计数排序
    ,最后反向一次;在示例中,这将在
    p1
    之前排序
    p5

    persons.stream().sorted(Comparator
                .comparing(Person::isFavorite)
                .thenComparing(Person::getCount).reversed())
        .forEach(System.out::println);
    

    您可以使用
    Comparator.comparing(…)。然后comparing(…)
    按多个属性排序。对于首先排序收藏夹,您可以按该属性排序,但随后必须反转结果,因为
    false
    true
    之前排序。假设您只想按
    计数
    是否为
    >0
    排序,而不是按计数的实际值排序:

    List<Person> persons = Arrays.asList(
            new Person("p1", 2, true),
            new Person("p2", 0, false),
            new Person("p3", 0, true),
            new Person("p4", 1, false),
            new Person("p5", 3, true));
    
    persons.stream().sorted(Comparator
                .comparing(Person::isFavorite).reversed()
                .thenComparing(p -> p.getCount() == 0))
        .forEach(System.out::println);
    
    请注意,最后的
    count==0
    条件是冗余的(假设
    count
    不能是
    <0

    或直接按
    计数排序
    ,最后反向一次;在示例中,这将在
    p1
    之前排序
    p5

    persons.stream().sorted(Comparator
                .comparing(Person::isFavorite)
                .thenComparing(Person::getCount).reversed())
        .forEach(System.out::println);
    

    您是否尝试过比较器。比较(…)。然后比较(…)?此外,还不清楚您是否要筛选或排序,如果您要排序,按照标准2和3排序的项目是否应保持原始顺序,或者您是否可以(例如)按照降序排序。@tobias_k说的是正确的。您是在尝试对集合进行排序,还是在尝试按条件显示person对象?如果这是第二个答案,一个简单的for-loop&if-else语句就足够了。您是否尝试过
    比较器。比较(…)。然后比较(…)
    ?此外,还不清楚您是要过滤还是排序,如果要排序,按照标准2和3排序的项目是否应保持原始顺序,或者你是否也可以,例如,按降序排列
    count
    。@tobias_k说的是真的。您是在尝试对集合进行排序,还是在尝试按条件显示person对象?如果这是第二个答案,那么一个简单的for-loop&if-else语句就足够了。即使使用Java7和更低版本,这个解决方案也可以实现。问题是基于Java8流对列表进行排序。这个解决方案甚至可以在Java7和更低版本中实现。问题是如何根据Java8流对列表进行排序。