如何在java中按两列对csv文件进行排序?
如何按两列对CSV文件进行排序?现在我可以按一列对它进行排序。我需要按前两列对其进行排序。怎么做?下面是我用于按第一列对其进行排序的代码:如何在java中按两列对csv文件进行排序?,java,sorting,csv,Java,Sorting,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.Tree
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.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并按一列或多列(字符串的
内容
内容)对其进行排序是一种非常通用的操作。它独立于域
可以实现一个比较器
,该比较器只需在列表
的多个索引处选取字符串,并按字典顺序比较这些索引处的值。使用此比较器
,可以对从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;
}
};
}
}
导入java.io.BufferedReader;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.io.Writer;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.List;
公共类多列CSVSORT
{
私有静态最终字符串列_SEPARATOR=“,”;
公共静态void main(字符串[]args)引发异常
{
InputStream InputStream=新文件InputStream(“sample input.csv”);
列表行=readCsv(inputStream);
//创建一个主要按列0排序的比较器,
//如果这些值相等,则按第2列
比较器比较器=创建比较器(0,2);
集合。排序(行、比较器);
OutputStream OutputStream=新文件OutputStream(“output.csv”);
String header=“符号、交换、最小值、平均值、最大值、总计”;
writeCsv(头、行、输出流);
}
私有静态列表readCsv(
InputStream(InputStream)引发IOException
{
BufferedReader reader=新的BufferedReader(
新的InputStreamReader(inputStream));
列表行=新的ArrayList();
//箕斗式掘进机
字符串行=reader.readLine();
while(true)
{
line=reader.readLine();
如果(行==null)
{
打破
}
List List=Arrays.asList(line.split(COLUMN_分隔符));
行。添加(列表);
}
回流线;
}
私有静态void writeCsv(
字符串标题、列表行、OutputStream(输出流)
抛出IOException
{
Writer Writer=新的OutputStreamWriter(outputStream);
writer.write(标题+“\n”);
用于(列表:行)
{
对于(int i=0;i private static使用适当的数据表示(即自定义类),列表
和比较器
,用于所需字段(使用集合#排序
)。我同意。您应该明确地将CSV文件解析为表示整体概念(股票报价?)的自定义类实例。很抱歉,我不知道该怎么做。是否读取整个文件,但只写入输出文件中的前两个排序列,并在第三列的单元格中分别写入值?我不确定“*在第三列的单元格中分别写入值*”是什么意思,但是:很容易修改writeCsv
方法来接收一个int
值的列表/数组,这些值指示应该写入哪些列,类似于createComparator
方法中的final int…index
的用法。我可以添加这样一个方法,但类名最初是Practice
,这表明你自己试试这个可能是个好主意,可能会带着更具体的问题回来;-)嗨,Marco13,我编辑了我的问题,更具体地说,是为了让你明白我的确切要求。:)如果我理解正确,你只需添加进一步的排序标准。你可以将我示例中的调用更改为createComparator(0,1,2,3);
根据所有列按字典顺序排序。不不不@Marco13!您不明白。:)我编辑了问题以添加实际需要的输出。第三列仅显示输入表(问题中的第一个表)第2列的最小值当第一列是ABC,第二列是X时,当它是ABC和Y时,则只有输入表第二列的最小值,依此类推。您现在明白了吗(
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));
}
}