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/