Ina
Ina

Reputation: 47

How to sort from text file and write into another text file Java

I have this textfile which I like to sort based on HC from the pair HC and P3

This is my file to be sorted (avgGen.txt):

7686.88,HC
20169.22,P3
7820.86,HC
19686.34,P3
6805.62,HC
17933.10,P3

Then my desired output into a new textfile (output.txt) is:

 6805.62,HC
17933.10,P3  
7686.88,HC
20169.22,P3  
7820.86,HC
19686.34,P3

How can I sort the pairs HC and P3 from textfile where HC always appear for odd numbered index and P3 appear for even numbered index but I want the sorting to be ascending based on the HC value?

This is my code:

public class SortTest {
 public static void main (String[] args) throws IOException{
    ArrayList<Double> rows = new ArrayList<Double>();
    ArrayList<String> convertString = new ArrayList<String>(); 
    BufferedReader reader = new BufferedReader(new FileReader("avgGen.txt"));

    String s;
    while((s = reader.readLine())!=null){
        String[] data = s.split(",");
        double avg = Double.parseDouble(data[0]);
        rows.add(avg);
    }

    Collections.sort(rows);

    for (Double toStr : rows){
        convertString.add(String.valueOf(toStr));
    }

    FileWriter writer = new FileWriter("output.txt");
    for(String cur: convertString)
        writer.write(cur +"\n");

    reader.close();
    writer.close();

  }
}

Please help.

Upvotes: 2

Views: 949

Answers (5)

Lijo
Lijo

Reputation: 6778

By using double loop sort the items then just comapre it using the loop and right in the sorted order

     public static void main(String[] args) throws IOException {
                ArrayList<Double> rows = new ArrayList<Double>();
                ArrayList<String> convertString = new ArrayList<String>(); 
                BufferedReader reader = null;
                try {
                    reader = new BufferedReader(new FileReader("C:/Temp/AvgGen.txt"));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                String s;
            try {
                while((s = reader.readLine())!=null){
                    String[] data = s.split(",");
                    convertString.add(s);
                    double avg = Double.parseDouble(data[0]);
                    rows.add(avg);
                }
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            FileWriter writer = new FileWriter("C:/Temp/output.txt");;
            Collections.sort(rows);
                 for (double sorted : rows) {
                     for (String value : convertString) {
                     if(Double.parseDouble(value.split(",")[0])==sorted)
                     {

                         writer.write(value +"\n");
                     }
                }

            }

Upvotes: 0

Yassin Hajaj
Yassin Hajaj

Reputation: 21975

Using , there is an easy way of performing this.

public static void main(String[] args) throws IOException {
    List<String> lines =
    Files.lines(Paths.get("D:\\avgGen.txt"))
         .sorted((a, b) -> Integer.compare(Integer.parseInt(a.substring(0,a.indexOf('.'))), Integer.parseInt(b.substring(0,b.indexOf('.')))))
         .collect(Collectors.toList());

    Files.write(Paths.get("D:\\newFile.txt"), lines);
}

Even better, using a Method reference

public static void main(String[] args) throws IOException {
    Files.write(Paths.get("D:\\newFile.txt"), 
                Files.lines(Paths.get("D:\\avgGen.txt"))
                     .sorted(Test::compareTheStrings)
                     .collect(Collectors.toList()));
}

public static int compareTheStrings(String a, String b) {
    return Integer.compare(Integer.parseInt(a.substring(0,a.indexOf('.'))), Integer.parseInt(b.substring(0,b.indexOf('.'))));
}

Upvotes: 0

Define a Pojo or bean representing an well defined/organized/structured data type in the file:

class Pojo implements Comparable<Pojo> {
    private double value;
    private String name;

    @Override
    public String toString() {
    return "Pojo [value=" + value + ", name=" + name + "]";
    }

    public double getValue() {
    return value;
    }

    public void setValue(double value) {
    this.value = value;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    /**
     * @param value
     * @param name
     */
    public Pojo(double value, String name) {
    this.value = value;
    this.name = name;
    }

    @Override
    public int compareTo(Pojo o) {

    return ((Double) this.value).compareTo(o.value);
    }

}

then after that: read->sort->store:

  public static void main(String[] args) throws IOException {
    List<Pojo> pojoList = new ArrayList<>();
    BufferedReader reader = new BufferedReader(new FileReader("chat.txt"));

    String s;
    String[] data;
    while ((s = reader.readLine()) != null) {
        data = s.split(",");
        pojoList.add(new Pojo(Double.parseDouble(data[0]), data[1]));
    }

    Collections.sort(pojoList);

    FileWriter writer = new FileWriter("output.txt");
    for (Pojo cur : pojoList)
        writer.write(cur.toString() + "\n");

    reader.close();
    writer.close();

    }

Upvotes: 0

Bon
Bon

Reputation: 3103

When you read from the input file, you essentially discarded the string values. You need to retain those string values and associate them with their corresponding double values for your purpose.

You can

  1. wrap the double value and the string value into a class,
  2. create the list using that class instead of the double value alone
  3. Then sort the list based on the double value of the class using either a Comparator or make the class implement Comparable interface.
  4. Print out both the double value and its associated string value, which are encapsulated within a class

Below is an example:

static class Item {
    String str;
    Double value;

    public Item(String str, Double value) {
        this.str = str;
        this.value = value;
    }
}
public static void main (String[] args) throws IOException {
    ArrayList<Item> rows = new ArrayList<Item>();
    BufferedReader reader = new BufferedReader(new FileReader("avgGen.txt"));

    String s;
    while((s = reader.readLine())!=null){
        String[] data = s.split(",");
        double avg = Double.parseDouble(data[0]);
        rows.add(new Item(data[1], avg));
    }

    Collections.sort(rows, new Comparator<Item>() {

        public int compare(Item o1, Item o2) {
            if (o1.value < o2.value) {
                return -1;
            } else if (o1.value > o2.value) {
                return 1;
            }
            return 0;
        }
    });

    FileWriter writer = new FileWriter("output.txt");
    for(Item cur: rows)
        writer.write(cur.value + "," +  cur.str + "\n");

    reader.close();
    writer.close();
}

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

When your program reads lines from the input file, it splits each line, stores the double portion, and discards the rest. This is because only data[0] is used, while data[1] is not part of any expression.

There are several ways of fixing this. One is to create an array of objects that have the double value and the whole string:

class StringWithSortKey {
    public final double key;
    public final String str;
    public StringWithSortKey(String s) {
        String[] data = s.split(",");
        key = Double.parseDouble(data[0]);
        str = s;
    }
}

Create a list of objects of this class, sort them using a custom comparator or by implementing Comparable<StringWithSortKey> interface, and write out str members of sorted objects into the output file.

Upvotes: 1

Related Questions