簡體   English   中英

比較CSV中的兩個arrayList

[英]Comparing two arrayLists from CSV

我有一個普遍的問題:

在以下情況下,根據彼此的值對兩個arraylists進行排序的最佳方法是:

(1)每個arrayList只包含導入CSV的一列(通過inputStream和bufferReader(為了方便起見,我不會在下面打印)。

//my arrayLists:

List <String> OpenVal = new Arraylist ();
List <String> CloseVal = new Arraylist();


//lists from above contain column 0 and 1 from CSV:
while((reader.readLine()) != null) {

Sting line = "";
String ColTwo [] = line.split(",");
openVal.add(colOne[1]);
closVal.add(colOne[2]);

(2)為了進一步清楚,CSV [colOne [1],colOne [2]的每一列包含以下信息:

//colOne [1]  colOne [2]
   date        value
   friday       32
   tues         21
   wed          5

(3)我對它進行排序的方式就像這樣(按值):

//colOne [1]  colOne [2]
   date        value
   wed          5
   tues         21
   friday       32

(4)我沒有找到一個有效的比較器類,因為我不需要將信息寫入arraylist的構造函數。 該列表以CSV為前綴。

(3)如何比較兩個列表的最佳方法?

如果您的csv每個日期只包含一行,您可以將數據存儲到map而不是list:

Map<String,Integer> myMap = new HashMap<>();
String line;
while((line = reader.readLine()) != null) {
    myMap.put(line.split(",")[0], Integer.parseInt(line.split(",")[1]));
}

之后您可以對地圖進行排序:

Map<String,Integer> sorted = myMap.entrySet().stream().
                             sorted(Map.Entry.comparingByValue()).
                             collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(e1, e2) -> e1,LinkedHashMap::new));

並打印您的有序地圖:

sorted.entrySet().forEach(System.out::println);

或者如DodgyCodeException所評論,將您的行讀取到List<String[]>

List<String[]> myList = new ArrayList<>();
    String line = "";
    while((line = reader.readLine()) != null) {
        myList.add(line.split(","));
}

並排序:

    Collections.sort(myList, new Comparator<String[]>() {
        @Override
        public int compare(String[] o1, String[] o2) {
            return Integer.compare(Integer.parseInt(o1[1]), Integer.parseInt(o2[1]));
        }
    });

最后打印列表只需使用for循環,例如:

for(String[] row : myList){
    System.out.println(row[0] +" : "+ row[1])
}

我可以想到兩個比解析成單獨的面向列的數組更好的路由。

  • 編寫一個包含成員字段的類來保存您的值,並使用其單個方法compareTo實現Comparable接口。 將對象實例化並收集到List ,然后調用Collections.sort 如果您還有其他工作要做,或者如果您有其他業務邏輯可以放在某處,那么這種方法最好。
  • 使用庫來解析CSV文件,並編寫一些代碼來對生成的元組進行排序。

我將展示第二個。

Apache Commons CSV庫

Apache Commons CSV庫在閱讀和編寫逗號分隔值制表符分隔文件方面對我有用 令人驚訝的是,這些格式有多種變體。 Commons CSV至少處理其中的九個。

首先,創建一個示例數據文件。 我改變了從第一列標題的自由datedowday-of-week更精確。

dow,value
friday,32
wed,5
tues,21

Commons CSV庫返回一個IterableCSVRecord對象。 CSV包含解析的CSV數據的一行中每列的值。 所以我們可以將這些對象用作元組

List.sort靜態方法將對我們收集的元組( CSVRecord對象)進行排序。 我們需要提供一個Comparator方法來對每個元組進行比較。 對於每個元組,我們通過在數據文件的第一行中定義的名稱(數據文件中的名稱value提取第二

List < CSVRecord > tuples = new ArrayList <>( 3 );
Reader reader = null;
try {
    reader = new FileReader( "/Users/basilbourque/data.csv" );
    CSVFormat csvFormat = CSVFormat.RFC4180.withIgnoreSurroundingSpaces( true ).withHeader();
    Iterable < CSVRecord > iterable = csvFormat.parse( reader );
    // Convert `Iterable` to a `List`. 
    for ( CSVRecord record : iterable ) {
        tuples.add( record );
    }
} catch ( FileNotFoundException e ) {
    e.printStackTrace();
} catch ( IOException e ) {
    e.printStackTrace();
}

Comparator < CSVRecord > comparator = new Comparator < CSVRecord >() {
    @Override
    public int compare ( CSVRecord o1 , CSVRecord o2 ) {
        Integer a = Integer.valueOf( o1.get( "value" ) );
        Integer b = Integer.valueOf( o2.get( "value" ) );
        return a.compareTo( b );
    }
};
System.out.println( "tuples before sort: \n" + tuples );
tuples.sort( comparator );
System.out.println( "tuples after sort: \n" + tuples );

排序前的元組:

[CSVRecord [comment = null,mapping = {dow = 0,value = 1},recordNumber = 1,values = [friday,32]],CSVRecord [comment = null,mapping = {dow = 0,value = 1}, recordNumber = 2,values = [wed,5]],CSVRecord [comment = null,mapping = {dow = 0,value = 1},recordNumber = 3,values = [tues,21]]]

排序后的元組:

[CSVRecord [comment = null,mapping = {dow = 0,value = 1},recordNumber = 2,values = [wed,5]],CSVRecord [comment = null,mapping = {dow = 0,value = 1}, recordNumber = 3,values = [tues,21]],CSVRecord [comment = null,mapping = {dow = 0,value = 1},recordNumber = 1,values = [friday,32]]]

最后,使用CSVRecord::get循環現在排序的元組列表,以便為其他目的提取數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM