根据 java 中的字段对自定义 Object class 进行多重排序

Multiple Sorting of an custom Object class by its field in java

package com.learnjava;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Stream;

public class EmployeeSortByGroup {

    public static void sortEmployeeByGrp(List<Person> persons, String[] sortBy){

        for(int i=0;i<sortBy.length;i++){
            switch (sortBy.length) {
            case 1:
                if(sortBy !=null && sortBy[0].contains("firstname")){
                    Collections.sort(persons, Comparator.comparing(Person::getFirstName));
                    }
                    if(sortBy !=null && sortBy[0].contains("lastname")){
                        Collections.sort(persons, Comparator.comparing(Person::getLastName));
                        }
                    if(sortBy !=null && sortBy[0].contains("age")){
                        Collections.sort(persons, Comparator.comparingInt(Person::getAge));
                        }
                    if(sortBy !=null && sortBy[0].contains("country")){
                        Collections.sort(persons, Comparator.comparing(Person::getCountry));
                    }
                    break;
            case 2:
                    if(sortBy !=null && sortBy[0].contains("firstname") && sortBy[1].contains("lastname")){
                    Collections.sort(persons, Comparator.comparing(Person::getFirstName).thenComparing(Person::getLastName));
                    }
                    if(sortBy !=null && sortBy[0].contains("firstname") && sortBy[1].contains("age")){
                        Collections.sort(persons, Comparator.comparing(Person::getFirstName).thenComparingInt(Person::getAge));
                        }
                    if(sortBy !=null && sortBy[0].contains("firstname") && sortBy[1].contains("country")){
                        Collections.sort(persons, Comparator.comparing(Person::getFirstName).thenComparing(Person::getCountry));
                        }

                break;
            case 3:
                //
            case 4:
                //
            default:
                break;
            }

        }

    }


    public static void main(String[] args) {

        try {

            Scanner sc=new Scanner(System.in);
            System.out.println("Enter number of rows : ");
            int rows=sc.nextInt();
            System.out.println("Enter sort by:");
            String sortByString=sc.next();

            String[] sortByStringArr=sortByString.split("\;");
            Stream<String> lines = Files.lines(
                    Paths.get("path to text file containing record")).skip(1).limit(rows);

            long lineCount = Files.lines(Paths.get("path to the text file containing record")).skip(1).limit(rows).count();


            Person[] persons = new Person[(int) lineCount];

            String[] stringArray = lines.toArray(String[]::new);

            for (int i=0;i<lineCount;i++){
                persons[i]=new Person();
                String[] perArr= stringArray[i].split("\|");
                    for (int j=0;j<perArr.length;j++){
                        persons[i].setFirstName((perArr[0]));
                        persons[i].setLastName((perArr[1]));
                        persons[i].setAge(Integer.parseInt(perArr[2]));
                        persons[i].setCountry((perArr[3]));
                    }
            }

            List<Person> t_arraylist = Arrays.asList(persons);
            sortEmployeeByGrp(t_arraylist,sortByStringArr);

            Stream.of(persons).forEach(s->System.out.println(s));
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

}

//Person class
package com.learnjava;

import java.util.Comparator;

public class Person {

     String FirstName;
     String LastName;
     int age;
     String country;
    public String getFirstName() {
        return FirstName;
    }
    public void setFirstName(String firstName) {
        FirstName = firstName;
    }
    public String getLastName() {
        return LastName;
    }
    public void setLastName(String lastName) {
        LastName = lastName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return ""+FirstName+"|"+LastName+"|"+age+"|"+country+"";
    }
    public Person() {
        super();
    }
    public Person(String firstName, String lastName, int age, String country) {
        super();
        FirstName = firstName;
        LastName = lastName;
        this.age = age;
        this.country = country;
    }
}

###这种方法的任何更好的解决方案。如果用户输入的行计数为 5,排序方式为 "firstname;age",那么它将对文件中的 5 行进行排序,不包括 header 的第一行,并先按名字排序,然后按年龄排序。更好的方法来处理所有这些用户输入的排序排列。

建立化合物Comparator incrementally using thenComparing(Comparator)

public static Comparator<Person> parseSortBy(String sortBy) {
    Comparator<Person> sortComparator = null;
    for (String field : sortBy.split(";")) {
        Comparator<Person> c;
        switch (field) {
            case "firstname":
                c = Comparator.comparing(Person::getFirstName);
                break;
            case "lastname":
                c = Comparator.comparing(Person::getLastName);
                break;
            case "age":
                c = Comparator.comparingInt(Person::getAge);
                break;
            case "country":
                c = Comparator.comparing(Person::getCountry);
                break;
            default:
                throw new IllegalArgumentException("Unknown sort spec: " + field);
        }
        sortComparator = (sortComparator == null ? c : sortComparator.thenComparing(c));
    }
    return sortComparator;
}

虽然我实际上会稍微改变一下,让方法只构建 Comparator,让调用者使用它。

我还会使该方法的一般部分可重用。

public static Comparator<Person> parsePersonSortBy(String sortBy) {
    return parseSortBy(sortBy, field -> {
        switch (field) {
            case "firstname": return Comparator.comparing(Person::getFirstName);
            case "lastname":  return Comparator.comparing(Person::getLastName);
            case "age":       return Comparator.comparingInt(Person::getAge);
            case "country":   return Comparator.comparing(Person::getCountry);
            default: throw new IllegalArgumentException("Unknown sort spec: " + field);
        }
    });
}
// The following method should be in a separate helper class for reusability
public static <E> Comparator<E> parseSortBy(String sortBy, Function<String, Comparator<E>> fieldComparatorMapper) {
    Comparator<E> sortComparator = null;
    for (String field : sortBy.split(";")) {
        Comparator<E> c = fieldComparatorMapper.apply(field);
        sortComparator = (sortComparator == null ? c : sortComparator.thenComparing(c));
    }
    return sortComparator;
}
// You will now use it like this. No need for using a List
Arrays.sort(persons, parsePersonSortBy(sortByString));

您现在可以轻松地增强解析以支持 降序 排序,例如通过在字段名称后添加一个 - 减号,这样 "firstname-;age" 将按 firstname 降序排序,然后按 age 升序排序。

public static <E> Comparator<E> parseSortBy(String sortBy, Function<String, Comparator<E>> fieldComparatorMapper) {
    Comparator<E> sortComparator = null;
    for (String field : sortBy.split(";")) {
        boolean descending = field.endsWith("-");
        Comparator<E> c = fieldComparatorMapper.apply(descending ? field.substring(0, field.length() - 1) : field);
        if (descending)
            c = c.reversed();
        sortComparator = (sortComparator == null ? c : sortComparator.thenComparing(c));
    }
    return sortComparator;
}