如何在java中对名字沿着年龄进行排序

k4emjkb1  于 2023-05-27  发布在  Java
关注(0)|答案(8)|浏览(102)

我是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);

    }
}
agxfikkp

agxfikkp1#

目前,您a)只通过一个属性进行比较,b)没有真正使用Java 8的新特性。
在Java 8中,你可以使用method references和链式比较器,如下所示:

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

这将比较两个Person示例,首先是它们的fname,如果相等,则是它们的age(对thenComparingInt进行了轻微优化以避免装箱)。

7nbnzgx9

7nbnzgx92#

你需要先比较一下名字。如果名字是一样的,那么也只有这样,结果才取决于年龄的比较

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

}}

如果你想从升序变成降序,只要改变符号就行了。例如

return -comp;

或者交换
姓名

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

年龄

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

jckbn6z73#

您的方法是正确的,但是您的compare方法是不完整的。
由于compare被调用来决定每一对中的哪一个项目在另一个之前,它必须包括所有的比较逻辑,而不仅仅是平局打破逻辑。您的代码仅根据年龄进行排序,而完全忽略名称。
逻辑应该是这样的:

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

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

mo49yndu

mo49yndu4#

您的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;
    }
}

您也可以考虑在Person类本身中实现Comparable<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;

    }
}
2hh7jdfx

2hh7jdfx5#

你可以使用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,它根据年龄和姓名进行比较

ih99xse1

ih99xse16#

这是一个简单的一行比较,使用三元运算符对对象进行排序。不需要写那么多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());

    }
});
0s0u357o

0s0u357o7#

//不使用比较器排序
import java.util.ArrayList; import java.util.List;
public class Uncategorized {

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

}

q8l4jmvw

q8l4jmvw8#

您可以简单地使用带有getName和getAge方法的静态引用的stream sorted方法。

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

相关问题