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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45769908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 08:53:16  来源:igfitidea点击:

How to sort the name along with age in java

javasortingcollections

提问by pawan sharma

I am new to Java 8. I just want to sort by the name. But the condition is: if there are duplicate names then it should be sorted according to age.

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

For example my input is

例如我的输入是

tarun  28
arun   29
varun  12
arun   22

and the output should be

并且输出应该是

arun   22
arun   29
tarun  28
varun  12

But I get something like

但我得到了类似的东西

varun  12
arun   22
tarun  28
arun   29

Means it's sorted either only by ages or names.

意味着它仅按年龄或名称排序。

This is the code which is implemented:

这是实现的代码:

POJO class:

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

Test class:

测试类:

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

    }
}

回答by Marvin

Currently you are a) only comparing by one attribute and b) not really making use of Java 8's new features.

目前,您 a) 仅通过一个属性进行比较,b) 没有真正利用 Java 8 的新功能。

With Java 8 you can use method referencesand chained comparators, like this:

在 Java 8 中,您可以使用方法引用和链式比较器,如下所示:

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

This will compare two Personinstances first by their fnameand - if that is equal - by their age(with a slight optimization to thenComparingIntto avoid boxing).

这将Person首先通过它们fname和 - 如果相等 - 通过它们age(稍微优化thenComparingInt以避免装箱)来比较两个实例。

回答by stefan bachert

You need to compare for names first. If the names are the same, then and only then the result depends on comparing the age

您需要先比较名称。如果名字相同,则且仅此结果取决于比较年龄

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

}}

if you want to change from ascending to descending, just change the sign. e.g.

如果要从升序变为降序,只需更改符号即可。例如

 return -comp;

or swap the person

或者换人

name

名称

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

age

年龄

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

回答by dasblinkenlight

You are on the right path, but your comparemethod is incomplete.

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

Since compareis called to decide which item in each pair is to go before the other, it must include all comparison logic, not only the tie-breaking one. Your code sorts on the age alone, ignoring the name completely.

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

The logic should go like this:

逻辑应该是这样的:

  • Compare names using t.getFname().compareTo(t1.getFname())
  • If names are notthe same, return the result of comparison
  • Otherwise, return the result of comparing ages.
  • 比较名称使用 t.getFname().compareTo(t1.getFname())
  • 如果名称一样,返回比较的结果
  • 否则,返回比较年龄的结果。

Proper way of comparing integers is with the static Integer.comparemethod, i.e. Integer.compare(t.getAge(), t1.getAge()).

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

回答by Dorian Gray

Your Comparatoris only sorting by age, not by name.

Comparator只是按年龄排序,而不是按名字排序。

You could try it like that:

你可以这样试试:

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

You could also think about implementing Comparable<Person>in the Personclass itself:

您还可以考虑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;

    }
}

回答by nagendra547

This is simple one linercomparison using ternary operator for sorting the objects. No need to write so many if/else block.

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

    }
});

回答by Vishwa Ratna

You can use Comparator.comparingmethod, introduced in Java 8, returns a Comparator object that will use the specified field as the sort key.

您可以使用Comparator.comparingJava 8 中引入的方法,返回一个 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);

We first created two lambda expressions, one to return the age of a given person and the other to return that person's name. We then combined these two lambda expressionsin the call to the sorted()method to compare on both properties. The comparing()method created and returned a Comparator to compare based on age. On the returned Comparator we invoked the thenComparing()method to create a composite comparatorthat compares based on both age and name

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

回答by soumya mishra

// Sort Without using Comparator

// 不使用比较器排序

import java.util.ArrayList; import java.util.List;

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

public class SortByNameThenAge {

公共类 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);
    }
}

}

}