用于CSV文件处理的Java数据类型
我在这个问题上绞尽脑汁寻找合适的数据类型来使用,但我无法确定哪种数据类型是在不使用任何第三方库的情况下最有效和最简单的编程方法: 问题: 考虑CSV文件中1990个月以来的每个公司的股票价格。文件格式如下,第一行为标题用于CSV文件处理的Java数据类型,java,csv,types,Java,Csv,Types,我在这个问题上绞尽脑汁寻找合适的数据类型来使用,但我无法确定哪种数据类型是在不使用任何第三方库的情况下最有效和最简单的编程方法: 问题: 考虑CSV文件中1990个月以来的每个公司的股票价格。文件格式如下,第一行为标题 Year,Month,Company A, Company B,Company C, .............Company N 1990, Jan, 10, 15, 20, , ..........,50 1990, Feb, 10, 15, 20, , ........
Year,Month,Company A, Company B,Company C, .............Company N
1990, Jan, 10, 15, 20, , ..........,50
1990, Feb, 10, 15, 20, , ..........,50
.
.
.
。
2013年9月50日10日15日500
输出:
列出股价最高的公司年度和月份
我已经考虑过使用树、Hashmap和列表,但我无法最终确定一个解决方案。我是一个Java新手,到目前为止已经有了几周的Java编码经验。任何形式的伪代码、程序或使用何种数据类型的帮助都将不胜感激 嗯。你应该把每一行读成一个字符串。然后,对于标题后面的每一行,您可能会遵循以下几种策略之一:创建一个日期数组,以及每个公司股票价格的浮动数组 或者创建一个公司对象,该对象本身具有一个数组(用于日期和股价)
您需要在公司对象中使用“addDatePrice(date,price)”方法。您可以根据标题csv行中的信息创建正确数量的公司(并为公司对象提供一个nam)好的,有无数种方法可以做到这一点,但我最喜欢的方法是创建一个Company类来保存Company.name、Company.month、Company.year、Company.price,并使用映射添加数据。然后添加逻辑将检查映射,查看是否存在同名的公司,如果不存在,或者新的Company price更大使用公司名称作为键将新的公司数据添加到映射中。下面的代码只是为了演示此目的,我将使用eclipse生成getter/setter,并使用这些getter/setter,而不是像演示一样使用直接成员变量。并且此演示缺少从CSV文件读取和收集公司数据的功能 CompanyLoader.java
package org.cnci.poc;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class CompanyLoader {
private List<Company> companies;
private int lastReadIdx=0;
public CompanyLoader() {
}
// Simply read the CSV and return the next set of company data
private Company getNextCompanyData() {
if (companies == null) {
lastReadIdx = 0;
try {
loadCompanies();
} catch (Exception e) {
}
}
if (companies == null) return null;
if (lastReadIdx < companies.size()) return companies.get(lastReadIdx++);
return null;
}
public void loadCompanies() throws Exception {
Scanner s = null;
try {
companies = new ArrayList<Company>();
File f = new File("test.csv");
System.out.println(f.getAbsolutePath());
s = new Scanner(new FileInputStream(f));
String[] headers = readLine(s);
System.out.println("headers: " + Arrays.toString(headers));
if (headers != null && headers.length >0) {
String[] data = null;
while ((data = readLine(s)) != null) {
System.out.println("data: " + Arrays.toString(data));
if (data.length != headers.length) {
companies = null;
throw new Exception("Invalid Data - headers count " + headers.length + " does not match with data count "+data.length);
}
String year = data[0];
String month = data[1];
for (int x=2; x<data.length; x++) {
double price = new Double(data[x]).doubleValue();
Company company = new Company(headers[x], year, month, price);
companies.add(company);
}
}
}
} finally {
if (s != null) s.close();
}
}
private String[] readLine(Scanner s) {
if (s.hasNextLine()) {
return s.nextLine().trim().split(",");
}
return null;
}
public void processCompanies() {
Map<String, Company> companies = new HashMap<String, Company>();
Company newCompany = null;
// repeat until all company data processed from CSV file
while ((newCompany = getNextCompanyData()) != null) {
Company oldCompany = companies.get(newCompany.getName());
if (oldCompany == null || newCompany.getPrice() > oldCompany.getPrice())
companies.put(newCompany.getName(), newCompany);
}
// Done, now display the winners
for (String name : companies.keySet()) {
Company company = companies.get(name);
System.out.println(company.getName() + " highest price " + company.getPrice() + " is " + company.getMonth() + " " + company.getYear());
}
}
public static void main(String[] args) {
CompanyLoader loader = new CompanyLoader();
loader.processCompanies();
}
}
test.csv
Year,Month,Company A,Company B,Company C,Company D,Company N
1990, Jan, 10, 15, 20, 31, 50
1990, Feb, 11, 14, 21, 30, 51
输出:
C:\Projects\Java\POC\test.csv
headers: [Year, Month, Company A, Company B, Company C, Company D, Company N]
data: [1990, Jan, 10, 15, 20, 31, 50]
data: [1990, Feb, 11, 14, 21, 30, 51]
Company B highest price 15.0 is Jan 1990
Company C highest price 21.0 is Feb 1990
Company N highest price 51.0 is Feb 1990
Company A highest price 11.0 is Feb 1990
Company D highest price 31.0 is Jan 1990
你尝试过什么?你在考虑如何使用
HashMap
或List
?对我来说似乎是一个正确的答案,除了一件事:使用对象而不是double
原语。double
是以精度换取速度的浮点值。创建double可能会在十进制分数中引入额外的数字选项。正如上面所说:[double]不应用于精确的值,例如货币。仔细想想,由于您没有对数字进行任何计算,在这种特殊情况下,使用double
是可以接受的(而不是BigDecimal)。通常是一个坏主意,但不是在这里。我的想法正好是在我选择双精度时,不必担心在没有任何计算的情况下溢出。有任何关于CSV解析的建议来适应解决方案吗?好了,完整的解决方案!享受吧!
C:\Projects\Java\POC\test.csv
headers: [Year, Month, Company A, Company B, Company C, Company D, Company N]
data: [1990, Jan, 10, 15, 20, 31, 50]
data: [1990, Feb, 11, 14, 21, 30, 51]
Company B highest price 15.0 is Jan 1990
Company C highest price 21.0 is Feb 1990
Company N highest price 51.0 is Feb 1990
Company A highest price 11.0 is Feb 1990
Company D highest price 31.0 is Jan 1990