我正面临着阅读某个number
并不是唯一的date
的问题,而index
也不是唯一的。
该程序计算量非常大,在我的ide上表现不佳,因此我面临使用正确数据结构的问题。
目前我创建了number
,我将date
读入一个HashMap,将HashMap
读入另一个public HashMap<String,String> getEventDates() throws Exception {
String csvFile = "C:\\Users\\test.csv";
CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
String [] line;
HashMap<String, String> eventMap = new HashMap<String, String>();
while ((line = reader.readNext()) != null) {
eventMap.put(line[15], line[13]);
}
reader.close();
return eventMap;
}
public HashMap<String,String> getNumberToEventDates() throws Exception {
String csvFile = "C:\\Users\\test.csv";
CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
String [] line;
HashMap<String, String> isinMap = new HashMap<String, String>();
while ((line = reader.readNext()) != null) {
isinMap.put(line[15], line[4]);
}
reader.close();
return isinMap;
}
。如果我需要它,我只是匹配它们。然而,读入需要两个函数,每个函数都有一个while循环。
line[15]
我应该使用哪种数据结构来更好地执行?如何合并这两种方法?
感谢您的回答!
更新
哦,我很抱歉。
事实上,在每次迭代{{1}}之后,这只是我创建的索引。
如何合并这两个功能?
答案 0 :(得分:4)
我认为你不应该使用两个函数,因为从文件读取速度较慢,而是将函数修改为,
public HashMap<String, SimpleEntry<String,String>> getEventDatesAndNumber() throws Exception
{
String csvFile = "C:\\Users\\test.csv";
CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
String [] line;
HashMap<String, SimpleEntry<String,String>> eventMap = new HashMap<String, SimpleEntry<String,String>>();
while ((line = reader.readNext()) != null)
{
eventMap.put(line[15], new SimpleEntry<String , String>(line[13],line[4]));
}
reader.close();
return eventMap;
}
修改强>
Tim B想法也不错,你有MapKey
类,然后你改变上面的方法,
public HashMap<String, MapKey> getEventDatesAndNumber() throws Exception
然后进行必要的更改。
答案 1 :(得分:1)
如果我理解你的唯一索引是数字和日期的组合,那么你想要查找从中映射的值吗?
处理此问题的方法是创建一个包含数字和日期的MapKey对象:
class MapKey {
final int number;
final Date date;
// Use Your IDE To generate equals and hash code. This is important!
}
然后只需要一个Map<MapKey, Data>
,您就可以通过执行
map.get(new MapKey(number, date));
如果您已经拥有MapKey对象而不是一直重新创建它,那么速度会更快,但如果您确实需要创建它,那就没什么大不了的了。
实际上再看一下,你似乎正在从一个值映射到两个值,所以要做到这一点,它将是另一种方式:
class Data {
int number;
Date date;
// Generate constructor etc in IDE
}
Map<String, Data> map = new HashMap<>();
然后只需要一个方法并将for循环更改为:
while ((line = reader.readNext()) != null) {
eventMap.put(line[15], new Data(line[13], line[4]));
}
答案 2 :(得分:1)
我将首先假设您的CSV数据是以某种理智的格式构建的。
NUM_HEADER,DATE_HEADER
NUM_VALUE,DATE_VALUE
NUM_VALUE,DATE_VALUE
假设以上情况属实,您基本上应该将CSV文件中的行转换为Java中的对象。通常使用与CSV文件中的值一对一匹配的属性。
所以你的代码看起来像这样。
public Events getEvents() throws Exception {
String csvFile = "C:\\Users\\test.csv";
CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
String [] line;
HashMap<String, String> eventMap = new HashMap<String, String>();
while ((line = reader.readNext()) != null) {
events.put(line[15], new Event(line[13], line[4]));
}
reader.close();
return events;
}
然后你还需要一个新的值类来将这两个变量放在一起。
class Event {
private int num;
private int date;
public Event(int date, int num) {
this.date = date;
this.num = num;
}
// Use Your IDE To generate equals and hash code. This is important! Because we're going to put this value class into a Java collection
}
Java collections - overriding equals and hashCode
最后是一个用于在一个不错的服务提供者中保存值类的类。
class Events {
private Map map = new HashMap<Integer, Event>;
public put(int uniqueId, Event event) {
map.put(uniqueId, event);
}
//Now you can offer any kind of domain specific services to the consumer of the Events class that you want.
}
我喜欢这种结构,因为它在客户端代码上非常容易。在Event and Events类中锁定了很多复杂性和簿记。您也可以在那里进行验证,并提供许多便利方法。
最后一步,根据您的使用情况,只需要在“事件”对象中包装所有内容。如果您想要的唯一功能是Map接口提供的确切功能,那么我就不会包装它。如果您需要特定于您的域的其他功能,那么我会将其包装起来。但通常我倾向于尽可能倾向于OO课程。从客户的角度来看,如果你正在处理Events
类而不是Map<foo,bar>
类,那么会更清楚。它在语义上更有意义,并且可以帮助客户了解正在发生的事情。