0

I have a csv file formed by two attributes: the first of type string and the second of type double.

Starting from this csv file, I would like to obtain another one, however, increasingly ordered based on the value of the second attribute. In SQL there was the ORDER BY function that allowed to order a database based on the specified attribute, I would like to get the same result as the ORDER BY.

Example input CSV file:

tricolor;14.0
career;9.0
salty;1020.0
looks;208.0
bought;110.0

Expected output CSV file:

career;9.0
tricolor;14.0
bought;110.0
looks;208.0
salty;1020.0
0

3 Answers 3

1

Read the CSV file into an List of Object[] (one Object[] per line in your CSV file)

  • First element of the array is the line itself (a String)
  • Second element of the array is the value of the double (a Double)

so you have the following list:

{ 
  ["tricolor;14.0", 14.0], 
  ["career;9.0", 9.0], 
  ["salty;1020.0", 1020.0],
  ["looks;208.0", 208.0],
  ["bought;110.0", 110.0]
}

Then sort it based on the value of the double

And you can then write it back to a CSV file (only writing the first element of each array)

List<Object[]> list = readFile("myFile.csv");
list.sort(Comparator.comparing(p -> (Double)p[1]));
// write to csv file, just printing it out here
list.forEach(p -> System.out.println(p[0]));

The method to read the file:

private static List<Object[]> readFile(String fileName) {
    List<Object[]> list = new ArrayList<>();
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
        String line;
        String[] splitLine;

        while ((line = br.readLine()) != null) {
            splitLine = line.split(";");
            // add an array, first element is the line itself, second element is the double value
            list.add(new Object[] {line, Double.valueOf(splitLine[1])});
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return list;
}

EDIT If you want reverse order:

Once you have your sorted list, you can reverse it using the convenient reverse method on the Collections class

Collections.reverse(list);
Sign up to request clarification or add additional context in comments.

2 Comments

one last thing. How should I modify list.sort (Comparator.comparing (p -> (Integer) p [1])); so that the ordering is decreasing rather than increasing?
@user3062889 I added an edit regarding reversing the list. Please upvote and accept my answer if it helped you. Thanks.
0

We can try the general approach of parsing the file into a sorted map (e.g. TreeMap), then iterating the map and writing back out to file.

TreeMap<String, Double> map = new TreeMap<String, Double>();

try (BufferedReader br = Files.newBufferedReader(Paths.get("yourfile.csv"))) {
    String line;
    while ((line = br.readLine()) != null) {
        String[] parts = line.split(";");
        map.put(parts[0], Double.parseDouble(parts[1]));
    }
}
catch (IOException e) {
    System.err.format("IOException: %s%n", e);
}

// now write the map to file, sorted ascending in alphabetical order

try (FileWriter writer = new FileWriter("yourfileout.csv");
    BufferedWriter bw = new BufferedWriter(writer)) {

    for (Map.Entry<String, Double> entry : map.entrySet()) {
        bw.write(entry.getKey() + ";" + entry.getValue());
    }
}
catch (IOException e) {
    System.err.format("IOException: %s%n", e);
}

Notes:

  • I assume that the string values in the first column would always be unique. If there could be duplicates, the above script would have to be modified to use a map of lists, or something along those lines.
  • I also assume that the string values would all be lowercase. If not, then you might not get the sorting you expect. One solution, should this be a problem, would be to lowercase (or uppercase) every string before inserting that key into the map.

1 Comment

Thanks. The string values are unique and lowercase.I would like the sort on the numerical value of the second second column or based on the number. I tried to run it and I get the following error: java.nio.charset.MalformedInputException: Input length = 2 at the line of code: while ((line = br.readLine ())! = null) { What can be the cause of the error?
0

get comma separated values into the LinkedHashMap

TreeMap<String, Double> map = new LinkedHashMap<String, Double>();

try (BufferedReader br = Files.newBufferedReader(Paths.get("yourfile.csv"))) {
    String line;
    while ((line = br.readLine()) != null) {
        String[] parts = line.split(";");
        map.put(parts[0], Double.parseDouble(parts[1]));
    }
}
catch (IOException e) {
    System.err.format("IOException: %s%n", e);
}

then sort the map based on double values.

try with java 8,

LinkedHashMap<String, Double> sortedMap;
sortedMap = map.entrySet().stream().sorted(Entry.comparingByValue()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.