2

I have an ArrayList containing Objects that have a date value. Now I want to manage to create a new ArrayList for each year that contains all the Objects from the main ArrayList that have the same year in their date Value.

So all Objects from 2010 go in one List, all from 1999 in another.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
tzippy
  • 6,458
  • 30
  • 82
  • 151
  • create list iterator and while iterating create new list for each distinct date entry, I don't know why would that make you do any good but its a try .. – ant May 27 '10 at 12:26
  • Did I get that wrong? Those `Object` s are `Date` s? Before answering (or even hearing) your question, I'd suggest using generics (http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.htm) to parameterize your `ArrayList`. – George May 27 '10 at 12:28
  • @Andeas_D: If you don't get a question, imagine a "How do I do that?" as third sentence. – tzippy May 27 '10 at 12:37

3 Answers3

14

You need a Map<Year,List<DatedObject>>, maybe even SortedMap like a TreeMap.

You can also use multimap from Guava.

Essentially you map from each year (perhaps just an Integer), the List<DatedObject> that belong in that year.

And since years have a natural sorting order, you may want to see if SortedMap provides you with functionalities that you need. Most likely the answer is yes.


The Map Example

Here's a snippet in Java that shows you how you can populate the map. Note also that NavigableMap is used instead of SortedMap; NavigableMap allows inclusive range queries (see related question).

    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)]}"

Related questions


The Partitioned List

If you absolutely insists on a List<List<DatedObject>> partitionedList, then build the map as above, and simply follow it with:

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)]]"

The MultiMap Example

You can also use Multimap from Guava, and Multimaps.index utility method as follows:

    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 Links

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
4
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);
}

I hope I didn't make much mistakes there..

fish
  • 1,050
  • 9
  • 13
4

The Multimaps.index() method in Guava will do this for you.

Kevin Bourrillion
  • 40,336
  • 12
  • 74
  • 87