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