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