尽管创建类作为 域的 适当表示通常是一个好主意:在这种情况下,我 不同意 注释。
读取CSV并按
String一列或多列的内容进行排序是非常通用的操作。并且它独立于域。
可以实现一个
Comparator简单地从a的多个索引处选择字符串
List<String>并按字典顺序比较这些索引处的值的a
。使用此工具
Comparator,可以对
List<List<String>>从CSV文件读取的任何内容进行排序。
这是一个简单的例子。它可用于根据任意列的字符串内容对 任何 CSV文件进行排序。
import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;public class MultiColumnCsvSort{ private static final String COLUMN_SEPARATOR = ","; public static void main(String[] args) throws Exception { InputStream inputStream = new FileInputStream("sample-input.csv"); List<List<String>> lines = readCsv(inputStream); // Create a comparator that sorts primarily by column 0, // and if these values are equal, by column 2 Comparator<List<String>> comparator = createComparator(0, 2); Collections.sort(lines, comparator); OutputStream outputStream = new FileOutputStream("output.csv"); String header = "Symbol, Exchange, Minimum, Average, Maximum, Total"; writeCsv(header, lines, outputStream); } private static List<List<String>> readCsv( InputStream inputStream) throws IOException { BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); List<List<String>> lines = new ArrayList<List<String>>(); // Skip header String line = reader.readLine(); while (true) { line = reader.readLine(); if (line == null) { break; } List<String> list = Arrays.asList(line.split(COLUMN_SEPARATOR)); lines.add(list); } return lines; } private static void writeCsv( String header, List<List<String>> lines, OutputStream outputStream) throws IOException { Writer writer = new OutputStreamWriter(outputStream); writer.write(header+"n"); for (List<String> list : lines) { for (int i = 0; i < list.size(); i++) { writer.write(list.get(i)); if (i < list.size() - 1) { writer.write(COLUMN_SEPARATOR); } } writer.write("n"); } writer.close(); } private static <T extends Comparable<? super T>> Comparator<List<T>> createComparator(int... indices) { return createComparator(MultiColumnCsvSort.<T>naturalOrder(), indices); } private static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return new Comparator<T>() { @Override public int compare(T t0, T t1) { return t0.compareTo(t1); } }; } private static <T> Comparator<List<T>> createComparator( final Comparator<? super T> delegate, final int... indices) { return new Comparator<List<T>>() { @Override public int compare(List<T> list0, List<T> list1) { for (int i = 0; i < indices.length; i++) { T element0 = list0.get(indices[i]); T element1 = list1.get(indices[i]); int n = delegate.compare(element0, element1); if (n != 0) { return n; } } return 0; } }; }}几年后更新:
如果要在各个列的排序顺序方面具有更大的灵活性,则有不同的选择。哪一个是“最佳”,很大程度上取决于您要如何“组装”实际的比较器-也就是说,您要如何定义应按
哪个 顺序对 哪一 列进行排序。但是,这里显示了一个简单的示例: __
import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;public class MultiColumnCsvSortExtended{ private static final String COLUMN_SEPARATOR = ","; public static void main(String[] args) throws Exception { InputStream inputStream = new FileInputStream("sample-input.csv"); List<List<String>> lines = readCsv(inputStream); // Create a comparator that compares the elements from column 0, // in ascending order Comparator<List<String>> c0 = createAscendingComparator(0); // Create a comparator that compares the elements from column 2, // in descending order Comparator<List<String>> c1 = createDesendingComparator(2); // Create a comparator that compares primarily by using c0, // and secondarily by using c1 Comparator<List<String>> comparator = createComparator(c0, c1); Collections.sort(lines, comparator); OutputStream outputStream = new FileOutputStream("output.csv"); String header = "Symbol, Exchange, Minimum, Average"; writeCsv(header, lines, outputStream); } private static List<List<String>> readCsv( InputStream inputStream) throws IOException { BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); List<List<String>> lines = new ArrayList<List<String>>(); String line = null; // Skip header line = reader.readLine(); while (true) { line = reader.readLine(); if (line == null) { break; } List<String> list = Arrays.asList(line.split(COLUMN_SEPARATOR)); lines.add(list); } return lines; } private static void writeCsv( String header, List<List<String>> lines, OutputStream outputStream) throws IOException { Writer writer = new OutputStreamWriter(outputStream); writer.write(header+"n"); for (List<String> list : lines) { for (int i = 0; i < list.size(); i++) { writer.write(list.get(i)); if (i < list.size() - 1) { writer.write(COLUMN_SEPARATOR); } } writer.write("n"); } writer.close(); } @SafeVarargs private static <T> Comparator<T> createComparator(Comparator<? super T>... delegates) { return (t0, t1) -> { for (Comparator<? super T> delegate : delegates) { int n = delegate.compare(t0, t1); if (n != 0) { return n; } } return 0; }; } private static <T extends Comparable<? super T>> Comparator<List<T>> createAscendingComparator(int index) { return createListAtIndexComparator(Comparator.naturalOrder(), index); } private static <T extends Comparable<? super T>> Comparator<List<T>> createDesendingComparator(int index) { return createListAtIndexComparator(Comparator.reverseOrder(), index); } private static <T> Comparator<List<T>> createListAtIndexComparator(Comparator<? super T> delegate, int index) { return (list0, list1) -> delegate.compare(list0.get(index), list1.get(index)); }}


