JAVA按列对CSV文件进行排序,然后按日期对列进行正确排序 [英] JAVA Sort CSV file by columns and then by a date column correctly

查看:304
本文介绍了JAVA按列对CSV文件进行排序,然后按日期对列进行正确排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清为什么我的日期排序不起作用.

I am trying to figure out why my date sorting isn't working.

我想按一些选择列(字符串)然后按日期列对CSV文件进行排序. 但是,它不能正确地对日期进行排序-似乎只是按日期的第一部分( 25 /12/2018)而不是确切的日期对它进行排序.

I want to sort a CSV file by some select columns(Strings) then by the date column. However it is not sorting the date correctly - its appears its just ordering it by the first part of the date (25/12/2018) and not the exact date.

public class MultiColumnCsvSort
{
private static final String COLUMN_SEPARATOR = ",";

public static void main(String[] args) throws Exception
{
    InputStream inputStream = new FileInputStream("order_lines_file.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(2,1,5);
    Collections.sort(lines, comparator);


    OutputStream outputStream = new FileOutputStream("output.csv");
    String header = "order id, sku, store, location, quantity, date";
    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?

但是,当我知道在这些值之间有日期的行时,输出如下所示: 当前排序的文件

However the output looks like the following when I know there are rows with dates between those values: current sorted file

推荐答案

YYYY-MM-DD(ISO 8601格式)

在日期的第一部分(2018年12月25日)而不是确切的日期排序.

ordering it by the first part of the date (25/12/2018) and not the exact date.

因此将字符串变形为标准 ISO 8601 格式(YYYY-MM-DD).按字母顺序排序的值也将按时间顺序排列.

So morph the string to standard ISO 8601 format (YYYY-MM-DD). Values sorted alphabetically will also be chronological.

定义一种格式设置以匹配您的输入.

Define a formatting pattern to match your inputs.

String input = "25/12/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

当然,您应该在实际代码中缓存DateTimeFormatter对象.请注意, java.time 类是线程安全,并使用不可变对象模式.

Of course you should cache the DateTimeFormatter object in your real code. Be aware that the java.time classes are thread-safe, and use the immutable objects pattern.

java.time 类在生成/解析字符串时默认使用标准的ISO 8601格式.因此,无需指定格式设置模式.

The java.time classes use the standard ISO 8601 formats by default when generating/parsing strings. So no need to specify a formatting pattern.

String output = ld.toString() ;  // Outputs standard format: YYYY-MM-DD

这篇关于JAVA按列对CSV文件进行排序,然后按日期对列进行正确排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆