Java 比较CSV中的两个ArrayList
我有一个一般性问题: 在以下情况下,根据两个ArrayList的值对其进行排序的最佳方法是什么: (1) 每个arrayList只包含一列导入的CSV(通过inputStream和bufferReader)(为了方便起见,我将不在下面打印) (3) 我对其进行排序的方式如下(按值): (4) 我不认为comparator类是有效的,因为我不需要向arraylist的构造函数写入信息Java 比较CSV中的两个ArrayList,java,arrays,sorting,arraylist,Java,Arrays,Sorting,Arraylist,我有一个一般性问题: 在以下情况下,根据两个ArrayList的值对其进行排序的最佳方法是什么: (1) 每个arrayList只包含一列导入的CSV(通过inputStream和bufferReader)(为了方便起见,我将不在下面打印) (3) 我对其进行排序的方式如下(按值): (4) 我不认为comparator类是有效的,因为我不需要向arraylist的构造函数写入信息 (3) 比较这两个列表的最佳方法是什么?如果csv每个日期只包含一行,则可以将数据存储到地图而不是列表: Map&
(3) 比较这两个列表的最佳方法是什么?如果csv每个日期只包含一行,则可以将数据存储到地图而不是列表:
Map<String,Integer> myMap = new HashMap<>();
String line;
while((line = reader.readLine()) != null) {
myMap.put(line.split(",")[0], Integer.parseInt(line.split(",")[1]));
}
或者正如DodgyCodeException所评论的,将您的行读到列表中
:
我可以想出两种比解析到单独的面向列的数组更好的方法
- 编写一个包含成员字段的类来保存您的值,并使用其单个方法实现接口。实例化对象并将其收集到
,然后调用列表中
。如果您有进一步的工作要做,或者如果您有其他业务逻辑要放在某个地方,这种方法是最好的集合。排序
- 使用库解析CSV文件,并编写一段代码对结果元组进行排序
date
的第一列标题从dow
更改为day of week
,更准确地说
道琼斯指数
2002年12月32日星期五
星期三,5
星期二,21
Commons CSV库返回一组对象。CSV包含一行解析的CSV数据中每列的值。因此,我们可以将这些对象用作一个对象
List.sort
静态方法将为我们收集的元组(CSVRecord
对象)进行排序。我们需要提供一种方法来对每个元组进行比较。对于每个元组,我们提取数据文件第一行中定义的第二个元组,即数据文件中的名称value
Listtuples=newarraylist(3);
Reader=null;
试一试{
reader=newfilereader(“/Users/basilbourque/data.csv”);
CSVFormat CSVFormat=CSVFormat.RFC4180.withIgnoreSurroundingSpaces(true).withHeader();
IterableIterable=csvFormat.parse(读卡器);
//将'Iterable'转换为'List'。
用于(CSVRecord记录:iterable){
tuples.add(记录);
}
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
比较器比较器=新比较器(){
@凌驾
公共整数比较(CSVRecord o1,CSVRecord o2){
整数a=Integer.valueOf(o1.get(“value”));
整数b=Integer.valueOf(o2.get(“value”));
返回a.compareTo(b);
}
};
System.out.println(“排序前的元组:\n”+元组);
元组排序(比较器);
System.out.println(“排序后的元组:\n”+元组);
排序前的元组:
[CSVRecord[comment=null,mapping={dow=0,value=1},recordNumber=1,value=[friday,32]],CSVRecord[comment=null,mapping={dow=0,value=1},recordNumber=2,value=[wed,5]],CSVRecord[comment=null,mapping={dow=0,value=1},recordNumber=3,value=[tues,21]]
排序后的元组:
[CSVRecord[comment=null,mapping={dow=0,value=1},recordNumber=2,value=[wed,5]],CSVRecord[comment=null,mapping={dow=0,value=1},recordNumber=3,value=[tues,21]],CSVRecord[comment=null,mapping={dow=0,value=1},recordNumber=1,value=[friday,32]]
最后,循环现在已排序的元组列表,使用
CSVRecord::get
提取数据以用于其他目的。@CrazySabPath它们恰好在本例中。您希望如何排序?值是什么?目前,我建议循环列表的大小,并比较它们的每个元素,因为您没有提供data,也不是您想要的排序方式。您希望如何对它们进行排序?值是什么意思?您能清楚地解释您想要的结果吗?@CrazySabPath我希望第二行的值位与第一行的日期值相对应,以便我可以对第二个值进行排序,并确保它正确链接到第一列date.我如何将此打印到控制台?是否为System.out.println(排序);?@DodgyCodeException谢谢。使用LinkedHashMap编辑我的答案以保持顺序。这在大多数情况下都有效-即只要Integer.parseInt(o1[1])-Integer.parseInt(o2[1])
不会导致算术溢出。这就是为什么会有一个方法Integer.compare(inta,intb)
。感谢您的回答@DodgyCodeException和@Eritrean!请澄清,当您引用return Integer.parseInt(o1[1])-Integer.parseInt(o2[1]);是否有[1]参考初始CSV中的列行?如果是这种情况,不是应该是[1]-[2]?@Leemi否,[1]指的是第2列,即“值”列。您要比较两行o1和o2的值字段。每行是一个2元素数组(字符串[2]
),其中[0]是第1列(日期),[1]是第2列(值)。答案中的最后一行应该是返回整数。比较(Integer.parseInt(o1[1]),Integer.parseInt(o2[1]);
//colOne [1] colOne [2]
date value
friday 32
tues 21
wed 5
//colOne [1] colOne [2]
date value
wed 5
tues 21
friday 32
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);
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(String[] row : myList){
System.out.println(row[0] +" : "+ row[1])
}