按值排序列CSV Java

时间:2019-04-17 15:01:55

标签: java csv sorting

我有一个由两个属性组成的csv文件:第一个属性为字符串类型,第二个属性为double类型。

从这个csv文件开始,我想获得另一个文件,但是,根据第二个属性的值,它越来越有序。在SQL中,有一个ORDER BY函数允许根据指定的属性对数据库进行排序,我希望得到与ORDER BY相同的结果。

示例CSV输入文件:

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

预期的输出CSV文件:

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

3 个答案:

答案 0 :(得分:1)

将CSV文件读入List中的Object[](CSV文件中每行一个Object[]

  • 数组的第一个元素是行本身(一个字符串)
  • 数组的第二个元素是double(Double)的值

所以您有以下列表:

{ 
  ["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]
}

然后根据double的值对其进行排序

然后您可以将其写回到CSV文件(仅写入每个数组的第一个元素)

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]));

读取文件的方法:

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;
}

编辑:如果要取消订单:

有了排序列表后,您可以使用reverse类上方便的Collections方法将其反转

Collections.reverse(list);

答案 1 :(得分:0)

我们可以尝试将文件解析为已排序的映射(例如TreeMap),然后迭代映射并写回到文件的一般方法。

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);
}

注意:

  • 我假设第一列中的字符串值将始终是唯一的。如果可能有重复项,则必须将上述脚本修改为使用列表列表或类似的内容。
  • 我还假定所有字符串值都是小写的。如果没有,那么您可能无法获得期望的排序。如果有问题,一种解决方案是在将该键插入到映射中之前,将每个字符串都小写(或大写)。

答案 2 :(得分:0)

将逗号分隔的值放入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);
}

然后根据双精度值对map进行排序。

尝试使用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));