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;
}
}
###Any better solution to this approach. If user input row count as 5 and sortBy as "firstname;age", then it will sort 5 rows from the file excluding the first row for header and sorting by firstname first and then by age. Better approach to handle all these permutations of sorting which user inputs.
Build a compound 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;
}
Though I would actually turn it around a bit, and let the method just build the Comparator
, leaving the caller to use it.
I would also make the general part of the method reusable.
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));
You can now easily enhance the parsing to support descending sorts, e.g. by added a -
minus sign after the field name, such that "firstname-;age"
would sort by firstname
descending, then by age
ascending.
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;
}