【问题标题】:Which java collection can I use?我可以使用哪个 java 集合?
【发布时间】:2012-05-13 13:37:47
【问题描述】:

我需要存储一组数据结构,这些数据结构由时间段(开始、结束)和该时间段的计数器定义,其中包含一些复杂的计算结果。数据结构的简化定义如下:

public class CounterBag {
    private Period period;   // collection key
    private Counter counter;
    // accessors
    // ...
}

Period 很简单:

public class Period {
    public DateTime start;
    public DateTime end;
    // accessors
    // ...
}

我需要一个包含由不同 Periods 定义的 CounterBag 对象的集合。 该集合需要通过long timeInMillis 提供有效的查找(这是捕获!),所以HashMap 不是一个真正的选择,因为我不想覆盖CounterBagequalshashcode(我需要他们俩)。集合需要按Period(按结束日期)排序。 Periods 具有灵活的持续时间,执行查找的部分不知道。

我想知道在 java 标准 API 或一些开源库中是否有一个开箱即用的集合可以帮助我解决它? 某种排序集或排序映射实现按日期高效查找。按日期查找将返回 CounterBagPeriod 日期在其中。

感谢您的建议。

【问题讨论】:

    标签: java collections dictionary map


    【解决方案1】:

    您可以使用 TreeMap 作为其排序集合(这使得查找高效)

    如果您的经期有固定间隔(这是最简单的形式),则您不需要这样的集合。您可以为每个间隔设置一个计数器。例如int[]

    【讨论】:

    • 谢谢,问题是Period 的开始和结束是灵活的,并且执行查找的部分不知道,因此查找将按日期而不是按期间完成。
    【解决方案2】:

    我只想扩展@Peter Lawrey 的答案,为您的 CounterBag 使用带有自定义比较器的 TreeMap。

    此比较器将确保返回范围内的 CounterBag。

    查找效率取决于您的比较器实现。

    【讨论】:

      【解决方案3】:

      如果句号不重叠,那么我建议使用TreeMap<Period, CounterBag>。当您需要以毫秒为单位获取给定时间 CounterBag 时,您可以使用以下命令:

      // Initialize map
      Map<Period, CounterBag> map = new TreeMap<Period, CounterBag>();
      map.put(...);
      
      // Prepare "query"
      long timeInMillis = ...;
      Period fakePeriod = new Period(new Date(timeInMillis), new Date(timeInMillis));
      
      // Get bag for given time.
      CounterBag bag = map.get(fakePeriod);
      

      在这种情况下,Period 必须实现 Comparable,或者您将自己的比较器传递给树。如果两个时期重叠,则比较它们应该返回 0(在我们的例子中,如果某个真实时期包括我们的假时期,其开始和结束时间等于 timeInMillis)。

      【讨论】:

        【解决方案4】:

        我建议TreeMap&lt;Long, CounterBag&gt;。您可以使用NavigableMap 接口访问它:

        NavigableMap<Long, CounterBag> map = new TreeMap<Long, CounterBag>();
        map.put(bag.period.end.toMillis(), bag); // Get end DateTime as a Long
        
        
        long lookupLong = 10000L; // or whatever
        
        /*
         * Retrieves the greatest Bag whose Period's end is
         * less than or equal to the Long
         */
        CounterBag newBag = map.floorEntry(lookupLong).getValue();
        

        【讨论】:

          【解决方案5】:

          因为任何开始时间都可能符合条件,给定足够的持续时间,按开始时间排序的简单 ArrayList 将是一种有效的方法,尤其是在允许重叠的情况下(产生多个结果)。您只需要迭代到开始时间 > 请求 timeInMillis 的第一条记录。

          【讨论】:

            猜你喜欢
            • 2014-03-25
            • 2013-01-23
            • 2011-05-16
            • 2011-05-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-11
            相关资源
            最近更新 更多