如何在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并将其按一列或多列的(字符串内容)排序是一种非常通用的操作.并且它独立于域.

可以实现一种比较器,该比较器简单地在List< String>的几个索引处选择字符串,并按字典顺序比较这些索引处的值.使用该比较器,可以对任何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-如何在不使用比较器和比较器接口的情况下对地图进行排序?如何编写自定义排序?


下一篇:mysql-使用SQL命令中的“按/排序”和合并联接为数百万行优化SSIS包