按包含的对象的属性拆分Java ArrayList

时间:2010-05-27 12:21:49

标签: java arraylist

我有一个ArrayList包含具有日期值的对象。 现在,我想设法为每年创建一个新的ArrayList,其中包含主ArrayList中与日期值相同年份的所有对象。

所以2010年的所有对象都在一个列表中,所有这些都来自1999年的另一个。

3 个答案:

答案 0 :(得分:12)

您需要一个Map<Year,List<DatedObject>>,甚至可能SortedMap就像一个TreeMap

您也可以使用multimap from Guava

基本上,您每年都会映射(可能只是一个Integer),即属于该年的List<DatedObject>

由于多年来有一个自然的排序顺序,您可能想看看SortedMap是否为您提供了所需的功能。很可能答案是肯定的。


地图示例

这是Java中的一个片段,向您展示如何填充地图。另请注意,NavigableMap代替SortedMap; NavigableMap允许包含范围查询(请参阅相关问题)。

    class DatedObject {
        final String name; final int year;
        DatedObject(String name, int year) {
            this.name = name; this.year = year;
        }
        @Override public String toString() {
            return String.format("%s (%d)", name, year);
        }
    }
    List<DatedObject> masterList = Arrays.asList(
        new DatedObject("A", 2010),
        new DatedObject("B", 2009),
        new DatedObject("C", 2006),
        new DatedObject("D", 2010),
        new DatedObject("E", 2009),     
        new DatedObject("F", 2011)          
    );
    NavigableMap<Integer,List<DatedObject>> objectsByYear =
        new TreeMap<Integer,List<DatedObject>>();
    for (DatedObject obj : masterList) {
        List<DatedObject> yearList = objectsByYear.get(obj.year);
        if (yearList == null) {
            objectsByYear.put(obj.year, yearList = new ArrayList<DatedObject>());
        }
        yearList.add(obj);          
    }
    System.out.println(objectsByYear);
    // prints "{2006=[C (2006)], 2009=[B (2009), E (2009)],
    //          2010=[A (2010), D (2010)], 2011=[F (2011)]}"
    System.out.println(objectsByYear.get(2011));
    // prints "[F (2011)]"
    System.out.println(objectsByYear.subMap(2007, true, 2010, true));
    // prints "{2009=[B (2009), E (2009)], 2010=[A (2010), D (2010)]}"

相关问题


分区列表

如果您绝对坚持使用List<List<DatedObject>> partitionedList,请按照上面的方式构建地图,然后按照以下步骤进行操作:

List<List<DatedObject>> partitionedList =
    new ArrayList<List<DatedObject>>(objectsByYear.values());
System.out.println(partitionedList);
// prints "[[C (2006)], [B (2009), E (2009)], [A (2010), D (2010)], [F (2011)]]"

MultiMap示例

您也可以使用Guava中的MultimapMultimaps.index实用工具方法,如下所示:

    Multimap<Integer,DatedObject> mmap = Multimaps.index(
        masterList,
        new Function<DatedObject, Integer>(){
            @Override public Integer apply(DatedObject from) {
                return from.year;
            }
        }
    );
    System.out.println(mmap);
    // prints "{2010=[A (2010), D (2010)], 2009=[B (2009), E (2009)],
    //          2006=[C (2006)], 2011=[F (2011)]}"

API链接

答案 1 :(得分:3)

Map<Integer, List<YourObject>> yearLists = new HashMap<Integer, List<YOurObject>>();
List<YourObject> originalList = ...; //initialized or received from somewhere

for (YourObject object : originalList) {
    int year = object.getDate().getYear(); //or something
    List<YourObject> yearList = yearLists.get(year);

    if (yearList == null) {
        yearList = new ArrayList<YourObject>();
    }

    yearList.add(object);
    yearLists.put(year, yearList);
}

我希望我在那里没有犯很多错误。

答案 2 :(得分:3)

Guava中的Multimaps.index()方法将为您完成此任务。