检查项目是否存在于Arraylist中的最有效方法是什么?

时间:2013-07-06 10:36:19

标签: java apache java-ee collections

最有效的方法是什么?

我有一个名为windowList的ArrayList列表。

GameWindow是具有startTime和endTime的bean。

对于我收到的每个对象,我需要检查对象的窗口属于这个windowList值的任何一个。我需要为数百万的价值做到这一点。

请以最有效的方式帮助我做到这一点......

1 个答案:

答案 0 :(得分:1)

建议:放弃ArrayList并使用SortedMap。我们在这里假设两件事:

  • 您的开始和结束时间是long(注意:为Java 7编写的代码);
  • 您的GameWindow班级正确实施了.equals().hashCode()

鉴于这些先决条件,请编写一个专门的类(例如,GameWindowList或其他),在其中声明:

final SortedMap<Long, List<GameWindow>> startTimes = new TreeMap<>();
final SortedMap<Long, List<GameWindow>> endTimes = new TreeMap<>();

然后添加一个窗口:

public void addGameWindow(final GameWindow window)
{
    final long startTime = window.startTime();
    final long endTime = window.endTime();
    List<GameWindow> list;

    // Insert in start times
    list = startTimes.get(startTime);
    if (list == null) {
        list = new ArrayList<>();
        startTimes.put(startTime, list);
    }
    list.add(window);

    // Insert in end times
    list = endTimes.get(endTime);
    if (list == null) {
        list = new ArrayList<>();
        endTimes.put(endTime, list);
    }
    list.add(window);
}

然后在给定时间内查看窗口:

public List<GameWindow> getWindowsForTime(final long time)
{
    // Submap of start times where the time is lower than or equal to
    // the requested time
    final SortedMap<Long, List<GameWindow>> validStartTimes 
        = startTimes.headMap(time);
    // Submap of end times where the time is greater than or equal to
    // the requested time
    final SortedMap<Long, List<GameWindow>> validEndTimes 
        = endTimes.tailMap(time);

    // Why GameWindow must implement equals and hashCode
    final Set<GameWindow> startSet = new HashSet<>();
    final Set<GameWindow> endSet = new HashSet<>();

    // Insert into the start set all game windows whose start time
    // is less than or equal to the requested time
    for (final List<GameWindow> list: startTimes.headMap(time).values())
        startSet.addAll(list);

    // Insert into the end set all game windows whose end time
    // is greater than or equal to the requested time
    for (final List<GameWindow> list: endTimes.tailMap(time).values())
        endSet.addAll(list);

    // Only retain the intersection of both sets
    startSet.retainAll(endSet);

    // Return the result
    return new ArrayList<>(startSet);
}

两个关键要素是:

  • SortedMap的{​​{1}}立即过滤掉所有开始或结束时间不合法的窗口;
  • .{tail,end}Map()用于仅保留开始时间和结束时间合法的窗口的交集;因此HashSet实施GameWindowhashCode()的重要性。