如何在java中对名称和年龄进行排序

时间:2017-08-19 09:28:07

标签: java sorting collections

我是Java 8的新手。我只想按名称排序。但条件是:如果有重复的名称,则应根据年龄对其进行排序。

例如我的输入是

tarun  28
arun   29
varun  12
arun   22

,输出应为

arun   22
arun   29
tarun  28
varun  12

但我有点像

varun  12
arun   22
tarun  28
arun   29

意味着它只按年龄或名字排序。

这是实施的代码:

POJO课程:

class Person {

    String fname;

    int age;

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public Person(String fname,  int age) {
        this.fname = fname;

        this.age = age;
    }

    @Override
    public String toString() {
        return fname  + age;
    }
}

测试类:

public class Test {

    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("tarun", 28));
        persons.add(new Person("arun", 29));
        persons.add(new Person("varun", 12));
        persons.add(new Person("arun", 22));

        Collections.sort(persons, new Comparator<Person>() {

            @Override
            public int compare(Person t, Person t1) {
                return t.getAge() - t1.getAge();
            }
        });
        System.out.println(persons);

    }
}

8 个答案:

答案 0 :(得分:8)

目前你只是a)仅通过一个属性进行比较而b)没有真正使用Java 8的新功能。

使用Java 8,您可以使用method references和链式比较器,如下所示:

Collections.sort(persons, Comparator.comparing(Person::getFname)
    .thenComparingInt(Person::getAge));

这将首先按Person比较两个fname实例,如果相等,则按age(略微优化thenComparingInt以避免装箱)比较两个{{1}}实例

答案 1 :(得分:3)

您走在正确的道路上,但您的compare方法不完整。

由于调用compare来决定每对中的哪个项目要先于另一个项目,因此它必须包括所有比较逻辑,而不仅仅是打破平局的逻辑。您的代码仅对年龄进行排序,完全忽略该名称。

逻辑应该是这样的:

  • 使用t.getFname().compareTo(t1.getFname())
  • 比较名称
  • 如果名称​​不相同,则返回比较结果
  • 否则,返回比较年龄的结果。

比较整数的正确方法是使用静态Integer.compare方法,即Integer.compare(t.getAge(), t1.getAge())

答案 2 :(得分:3)

您需要首先比较名称。 如果名称相同,那么结果只取决于比较年龄

public static void main(String[] args) {
    List<Person> persons = new ArrayList<>();
    persons.add(new Person("tarun", 28));
    persons.add(new Person("arun", 29));
    persons.add(new Person("varun", 12));
    persons.add(new Person("arun", 22));

    Collections.sort(persons, new Comparator<Person>() {

        public int compare(Person t, Person t1) {
            int comp = t.getFname().compareTo(t1.getFname());
            if (comp != 0) {    // names are different
                return comp;
            }
            return t.getAge() - t1.getAge();
        }
    });
    System.out.println(persons);

}}

如果您想要从升序变为降序,只需更改符号即可。 e.g。

 return -comp;

或交换此人

名称

 int comp = t1.getFname().compareTo(t.getFname());

年龄

 return t1.getAge() - t.getAge();

答案 3 :(得分:1)

您的Comparator仅按年龄排序,而不是按名称排序。

你可以这样试试:

new Comparator<Person>() {
    @Override
    public int compare(Person t, Person t1) {
        int ret = t.getFname().compareTo(t1.getFname());
        if (ret == 0) {
           ret = Integer.compare(t.getAge(), t1.getAge()); 
        }
        return ret;
    }
}

您还可以考虑在Comparable<Person>类本身中实现Person

class Person implements Comparable<Person> {
    @Override
    public int compareTo(Person p) {
        int ret = fname.compareTo(p.fname);
        if (ret == 0) {
           ret = Integer.compare(age, p.getAge()); 
        }
        return ret;

    }
}

答案 4 :(得分:0)

这是使用三元运算符对对象进行排序的简单 one liner 比较。 无需编写如此多的if / else块

Collections.sort(persons, new Comparator<Person>() {

    @Override
    public int compare(Person t1, Person t2) {

        return t1.getFname().equals(t2.getFname()) ? t1.getAge()-t2.getAge() : t1.getFname().compareTo(t2.getFname());

    }
});

答案 5 :(得分:0)

您可以使用Java 8中引入的Comparator.comparing方法,返回一个Comparator对象,该对象将使用指定的字段作为排序键。

final Function<Person, Integer> byAge = person -> person.getAge();   
final Function<Person, String> byTheirName = person -> person.getFname();
System.out.println("Sorted in ascending order by age and name: ");
        List<Person> sortedlist =   people.stream()
            .sorted(Comparator.comparing(byAge).thenComparing(byTheirName))
            .collect(Collectors.toList());
        sortedlist.forEach(System.out::println);

我们首先创建了两个lambda表达式,一个用于返回给定人物的年龄,另一个用于返回该人的名字。然后,我们在调用sorted()方法的过程中组合了这两个 lambda表达式,以比较这两个属性。 comparing()方法创建并返回一个Comparator以便根据年龄进行比较。在返回的Comparator上,我们调用了thenComparing()方法,以创建一个基于年龄和姓名进行比较的复合comparator

答案 6 :(得分:0)

//不使用比较器进行排序

import java.util.ArrayList; 导入java.util.List;

公共类SortByNameThenAge {

static class Student {
    String name;
    int age;

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

}

public static void main(String[] args) {
    List<Student> olist = new ArrayList<>();
    olist.add(new Student("Sam", 26));
    olist.add(new Student("Sam", 22));
    olist.add(new Student("Abc", 25));
    olist.add(new Student("Abc", 22));
    olist.add(new Student("Abc", 23));
    olist.add(new Student("Sam", 24));
    olist.add(new Student("Sam2", 21));
    olist.add(new Student("Sam2", 19));
    // Order By name
    for (int i = 0; i < olist.size(); i++) {
        for (int j = olist.size() - 1; j > i; j--) {
            if (olist.get(i).name.compareTo(olist.get(j).name) > 0) {
                Student temp = olist.get(i);
                olist.set(i, olist.get(j));
                olist.set(j, temp);
            }
        }
    }

    for (Student s : olist) {
        System.out.println(s.name + " : " + s.age);
    }

    // Order by name then age
    for (int i = 0; i < olist.size(); i++) {
        for (int j = i+1; j < olist.size(); j++) {
            if (olist.get(i).name.compareTo(olist.get(j).name) == 0) {
                if (olist.get(i).age > olist.get(i + 1).age) {
                    Student temp = olist.get(i);
                    olist.set(i, olist.get(i + 1));
                    olist.set(i + 1, temp);
                }
            }
        }
    }
    System.out.println("\nSorting by age keeping name as it is");

    for (Student s : olist) {
        System.out.println(s.name + " : " + s.age);
    }
}

}

答案 7 :(得分:0)

您可以简单地将流排序方法与getName和getAge方法的静态引用一起使用。

List<Person> list=new ArrayList<Person>();
list.stream().sorted(Comparator.comparing(Employee::getName).thenComparing(Employee::getAge)).collect(Collectors.toList()).forEach(System.out::println);