如何用Java中的两列对csv文件进行排序?

如何按两列对CSV文件进行排序?现在,我可以按一列对其进行排序。我需要按前两列对其进行排序。怎么做?这是我用来按其第一列进行排序的代码:

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.FileWriter;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import java.util.TreeMap;

public class Practice {

public static void main(String[] args) throws Exception {

BufferedReader reader = new BufferedReader(new FileReader("sample-input.csv"));

Map<String, List<String>> map = new TreeMap<String, List<String>>();

String line = reader.readLine();//read header

while ((line = reader.readLine()) != null) {

String key = getField(line);

List<String> l = map.get(key);

if (l == null) {

l = new LinkedList<String>();

map.put(key, l);

}

l.add(line);

}

reader.close();

FileWriter writer = new FileWriter("output.csv");

writer.write("Symbol, Exchange, Minimum, Average, Maximum, Total\n");

for (List<String> list : map.values()) {

for (String val : list) {

writer.write(val);

writer.write("\n");

}

}

writer.close();

}

private static String getField(String line) {

return line.split(",")[0];

// extract value you want to sort on

}

}

编辑:两列排序后的输出变为:

ABC,X,0.10,10

ABC,X,0.09,20

ABC,X,0.11,10

ABC,X,0.11,20

ABC,X,0.10,10

ABC,Y,0.09,10

ABC,Y,0.08,10

ABC,Z,0.12,15

ABC,Z,0.10,15

DEF,X,0.17,10

DEF,X,0.14,10

DEF,Y,0.15,15

DEF,Y,0.15,15

DEF,Y,0.17,15

DEF,Y,0.16,15

DEF,Y,0.17,15

DEF,Z,0.14,10

DEF,Z,0.15,10

我需要这样的输出:

ABC,X,0.09,0.11

ABC,X,0.09,0.11

ABC,X,0.09,0.11

ABC,X,0.09,0.11

ABC,X,0.09,0.11

ABC,Y,0.08,0.9

ABC,Y,0.08,0.9

ABC,Z,0.10,0.12

ABC,Z,0.10,0.12

DEF,X,0.14,0.17

DEF,X,0.14,0.17

DEF,Y,0.15,0.17

DEF,Y,0.15,0.17

DEF,Y,0.15,0.17

DEF,Y,0.15,0.17

DEF,Y,0.15,0.17

DEF,Z,0.14,0.15

DEF,Z,0.14,0.15

但是,我希望第三列显示当前在第三列中显示的值中X的最小值,然后显示Y的最小值,然后显示Z。

回答:

尽管创建类作为 域的 适当表示通常是一个好主意:在这种情况下,我 注释。

读取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));

}

}

以上是 如何用Java中的两列对csv文件进行排序? 的全部内容, 来源链接: utcz.com/qa/407115.html

回到顶部