java - java中自定义对象类按其字段进行多重排序

标签 java sorting chained

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,sortBy 为“firstname;age”,那么它将对文件中的 5 行进行排序,不包括标题的第一行,并先按名字排序,然后按年龄排序。更好的方法来处理对用户输入进行排序的所有这些排列。

最佳答案

build 一个大院Comparator 增量使用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 降序排序,然后按 >年龄升序。

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

关于java - java中自定义对象类按其字段进行多重排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59882928/

相关文章:

option - 根据另一个下拉选择的值 react 选择链式选项

java - Tomcat 未处理 jSTL ${}

java - 更一般地查找列表的最大值

mysql - 测验布局改进

javascript - 单击时删除项目并将这些项目移动到列表底部

paypal - 将运费添加到 PayPal 简单链式支付?

java - Token/TokenSession 拦截器导致 HttpSession 上出现空指针

Java应用程序导出

c++ - 为什么我的替代排序算法不起作用?

jquery - Joomla JForm 使用外键、Ajax 和 jQuery 链接选择