0

Currently, I'm at the point where I have only sorted the names within the file but I want to also make it so that ages can be sort. Another problem would be trying to get names that are the same but have different ages to sort. Right now my code looks something like this:

import java.io.BufferedReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


public class MultiKey {

    public static void main(String[] args) {
        File textFile = new File("H:\\Names_ages.txt");
        FileReader in;
        BufferedReader readFile;
        String lineOfText;

        try {
            in = new FileReader(textFile);
            readFile = new BufferedReader(in);
            BufferedReader reader = new BufferedReader(new FileReader(textFile));
            List<String> results = new ArrayList<String>();
            while ((lineOfText = readFile.readLine()) != null) {
                results.add(lineOfText);

            }
            Collections.sort(results);
            System.out.println(results);


            readFile.close();
            in.close();
        } catch (FileNotFoundException e){
            System.out.println("File does not exist or could not be found");
            System.err.println("FileNotFoundException: "+ e.getMessage());
        } catch (IOException e){
            System.out.println("Problem reading file");
            System.err.println("IOException: " + e.getMessage());
        }
    }
}
  • 1
    if you want to sort your collection in multiple ways, you can do this by writing comparators, http://stackoverflow.com/questions/5245093/using-comparator-to-make-custom-sort comparators allow you to sort a collection based on a specified method. – chatton Nov 08 '16 at 16:52
  • Just a note the output I'm getting right now is: [Abrams 15, Alexander 22, Herkman 12, Jones 11, Jones 14, Jones 2, Jones 9, Smith 17, Smith 19, Smith 20, Tippurt 42] – Aldo Chen Nov 08 '16 at 16:53
  • You should als look into [`try-with-resources`](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html). – bradimus Nov 08 '16 at 16:53
  • You're just naturally sorting String there. Also, you didn't show us the file line format, and on the other hand there's lots of irrelevant code there for the question being asked. Please read https://stackoverflow.com/help/mcve – ericbn Nov 08 '16 at 16:56

3 Answers3

1

Logic:

  • Create a separate holder for the attributes you want to have the sorting on.
  • Apply Comparator on that Person object.

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.lang.reflect.Array;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    
    public class MultiKey {
    
        public static void main(String[] args) {
            File textFile = new File("H:\\Names_ages.txt");
            FileReader in;
            BufferedReader readFile;
            String lineOfText;
    
            try {
                in = new FileReader(textFile);
                readFile = new BufferedReader(in);
                BufferedReader reader = new BufferedReader(new FileReader(textFile));
                List<Person> results = new ArrayList<Person>();
                while ((lineOfText = readFile.readLine()) != null) {
                    //split here the line into name and age separate variables basedon delimiter available between them.
                    Person p = new Person(name,age);
                    results.add(p);
    
                }
                order(results);
                System.out.println(results);
    
    
                readFile.close();
                in.close();
            } catch (FileNotFoundException e){
                System.out.println("File does not exist or could not be found");
                System.err.println("FileNotFoundException: "+ e.getMessage());
            } catch (IOException e){
                System.out.println("Problem reading file");
                System.err.println("IOException: " + e.getMessage());
            }
        }
    }
    
    private static void order(List<Person> persons) {
    
        Collections.sort(persons, new Comparator<Person>() {
    
            public int compare(Object o1, Object o2) {
    
                String x1 = ((Person) o1).getName();
                String x2 = ((Person) o2).getName();
                int sComp = x1.compareTo(x2);
    
                if (sComp != 0) {
                   return sComp;
                } else {
                   Integer x1 = ((Person) o1).getAge();
                   Integer x2 = ((Person) o2).getAge();
                   return x1.compareTo(x2);
                }
        }});
    }
    
    public class Person{
    private String name;
    private int age;
    
    public String getName(){
    return this.name;
    }
    
    public void setName(String name){
    this.name = name;
    }
    
    public int getAge(){
    return this.age;
    }
    
    public vois setAge(int age){
    this.age = age;
    }
    

    }

mhasan
  • 3,703
  • 1
  • 18
  • 37
0

Typical Approach would be:

  • Parse each line and create an encapsulation object for it (in your example a class "Person" with two fields for "name" and "age") How you do this parsing depends on the format of the lines in the file e.g. you can use String.split(",") for this, if the values in the line are separated by comma.

  • Add the encapsulation objects to a list and then e.g. sort using a Comparator. Use java.util.Collections.sort(Comparator).

Of course, with that list of encapsulation objects you can do much more very easily, e.g. find Persons with same Name but different Ages.

Thomas Philipp
  • 261
  • 1
  • 5
0

You can use the thenComparing to chain Comparators

    Comparator<String> byName = Comparator.comparing(s -> s.split(" ")[0]);
    Comparator<String> byAge = Comparator.comparingInt(s -> Integer.parseInt(s.split(" ")[1]));

    try (BufferedReader br = new BufferedReader(new FileReader("filePath"))) {
        List<String> sorted = br.lines().sorted(byName.thenComparing(byAge)).collect(Collectors.toList());
        return sorted;
    } catch (IOException e) {
        e.printStackTrace();
    }

If more than one space also expected try pattern \\s+ instead of white space

or we can create a Comparator like below instead of creating two Comparators

    Comparator<String> c = Comparator.<String, String> comparing(s -> s.split("\\s+")[0])
            .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1]));
Saravana
  • 12,647
  • 2
  • 39
  • 57