【问题标题】:Finding index in an ArrayList在 ArrayList 中查找索引
【发布时间】:2016-08-28 22:05:23
【问题描述】:

我有一个 CSV 文件,我在 Java 中存储为数组列表。这是我运行的代码

public class StockData {
private ArrayList<StockRecord> records;

public StockData() {
    records = new ArrayList<StockRecord>();
}

//reads the file from the folder
public void loadPriceData(String filepath) {
    try {
        Scanner scanner = new Scanner(new FileReader(filepath));
        String line;
        StockRecord record;
        scanner.nextLine();
        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            String[] results= line.split(",");
            double open = Double.parseDouble( results[1]);
            double high = Double.parseDouble( results[2]);
            double low = Double.parseDouble( results[3]);
            double close = Double.parseDouble( results[4]);
            double volume = Double.parseDouble( results[5]);
            double adjClose = Double.parseDouble( results[6]);
            //create the record
            record = new StockRecord(results[0], open, high, low, close, volume, adjClose);
            records.add(record);
        }
        scanner.close();
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
}

}

代码可以正常工作,但是我在项目的下一部分遇到了问题。 数据示例

  1. 日期开盘高低收盘成交量调整收盘
  2. 6/10/2011 128.85 128.93 127.26 127.6 238629400 126.97
  3. 6/13/2011 127.89 128.24 127.05 127.7 207599800 127.07
  4. 6/14/2011 128.87 129.77 128.82 129.32 160570400 128.68
  5. 6/15/2011 128.24 129.3 126.68 127.02 300958000 126.39
  6. 6/16/2011 127.06 127.97 126.32 127.3 308032800 126.67

我正在尝试打印某个日期范围的 AdjClose 价格。比如说在 2011 年 6 月 13 日到 2016 年 6 月 15 日之间。看来我需要先找到日期的索引,然后打印价格记录。

我该怎么做?我不知道从哪里开始。我是否首先需要将日期保存在自己的列表/数组中并使用它来查找索引?

谢谢

【问题讨论】:

  • 您将日期存储为字符串,这将使它们难以比较。您可以将它们存储为 java.time.LocalDate。

标签: java csv arraylist indexing


【解决方案1】:

您需要遍历 StockRecord 列表并将每条记录的日期与您指定的范围进行比较。如果它落在范围内,您将打印它。如果您的列表已排序,则可以对此进行优化。

【讨论】:

    【解决方案2】:

    比较第一个日期最好使用数据类型date

    如果您的数组可以搜索 StockRecord 类型的记录和对象,比较您想要评估的日期字段

    for (StockRecord reg : records) {
            if(reg.date.after(historyDate) && reg.date.before(futureDate)) {
               System.out.println(reg.toString()); // print object
            }
        }
    

    【讨论】:

    • 信息不正确。您提到了旧的遗留类 java.util.Date,但随后列出了一个完全不同的类 java.time.LocalDate 的方法。
    • 提一下比较前后日期的方法,哪里错了?
    • 您将java.util.Datejava.time.LocalDate 混为一谈,这是两个完全不同且不相关的类,第一个来自Java 1,另一个来自Java 8。java.util.Date 类提供after、@987654327 @、equalscompareTo 用于比较。您列出了其他类的方法。但实际上应该完全避免这个java.util.Date 类,以及它的兄弟类java.util.Calendar。设计不佳,令人困惑和麻烦。现在被 java.time 类所取代。
    • 是对的,我知道一个有效的选项,但可能不是最好的。谢谢你的提示我马上研究
    【解决方案3】:

    您的问题确实与 Stack Overflow 中的许多其他问题重复。

    LocalDate

    您的示例代码实际上并未将日期显示为 StockRecord 类的一部分。但它应该是LocalDate 类型的成员。在 Stack Overflow 上搜索无数关于如何将输入字符串解析为 LocalDate 的帖子。

    Comparator

    为您的班级定义一个Comparator,以提取LocalDate 进行比较。 LocalDate 类本身实现了compareTo 方法,以及isBeforeisAfterisEqual

    排序的好处

    如果您将经常执行此查询,那么将StockRecord 对象排序为List 是有意义的。然后你就可以聪明地搜索了,这在 Stack Overflow 的许多其他帖子中再次讨论过。

    SortedMap

    您可以将StockRecord 对象组织成一个SortedMap,将LocalDate 映射到共享该特定日期的StockRecord 对象的Collection。如上所述,使用SortedMap 而不仅仅是Map 可以让您更智能地搜索日期范围。同样,Stack Overflow 上有很多关于地图的帖子。

    Apache Commons CSV

    顺便说一句,Apache Commons CSV 项目可以轻松读取和解析 CSV 数据文件。

    BigDecimal

    不要doubleDouble 用于货币金额,或用于任何需要准确性的小数。这些类型是floating-point 类型,专为速度而设计,但牺牲了准确性。您将在小数部分的末尾引入无关的额外数字。

    改为使用BigDecimal。再说一次,这门课上有很多关于 Stack Overflow 的帖子。

    整数

    不要将Double 之类的小数用于Volume 字段之类的整数。这样做会浪费内存,并使任何阅读您的代码的人感到困惑。

    如果您的最大值为 20 亿或更少 (2^31-1 = 2,147,483,647),则使用 32 位 integerInteger,否则使用 64 位 longLong

    【讨论】:

      猜你喜欢
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多