udon
udon

Reputation: 103

Java List of List of List, better solution?

I created a class name objectA that has lets say 4 variable: Date time; String text; int var1, int var2

I need to create a list of ObjectA(). And then group them first by Time, second by var1, and then by var2. This is because i want to be able to compare lists that has different var2 but the same var1; or lists that has the same var2 but different var1.

I end up using "List< List< List< objectA>>>" which works fine i guess, but it doesnt looks great. And i dont think this is a good practice. Does anyone know any Datastructure or Tree or other ideas with which i could implement instead of List within List within List.

The list of object may look something like this

Almost similar question has actually been ask here: List of Lists of Lists .But the answer are just not what i was looking for. Please pardon me if this is still consider against the rule.

Upvotes: 1

Views: 526

Answers (4)

geneSummons
geneSummons

Reputation: 925

If that's always the way you want to sort; by time, then val1, then val2, implement Comparable in your ObjectA class. Something like

public int compareTo(Object that) {
    //check for null
    // check for instanceOf ObjectA
    // cast from Object to ObjectA
    int result = this.time.compareTo(that.time);
    if (result == 0) {
       // time comparison was the same
       result = this.var1.compareTo(that.var1);
       if (result == 0) {
           // time and var1 comparisons were the same
           result = this.var2.compareTo(that.var2)
       }
    }
    return result;
}

and then just sort() one list.

Upvotes: 0

fps
fps

Reputation: 34460

The ideal structure to group objects by some attribute is a Map of Lists, where each key of the map corresponds to each different value of the attribute along the list of objects, and each value of the map is a sublist of all the objects whose attribute matches the key.

Let's start grouping by a single attribute. Using streams is quite easy to accomplish what you want:

Map<Date, List<ObjectA>> groupsByDate = 
    yourList.stream()
        .collect(Collectors.groupingBy(ObjectA::getTime));

This assumes ObjectA has a getTime method.

Now, Collectors.groupingBy has an overloaded version that accepts what is called a downstream collector, meaning that you can collect the objects that match a value into another structure different than a List.

For example, you can collect to a second Map that groups objects by a second criteria, in your case this would be by var1:

Map<Date, Map<String, List<ObjectA>>> groupsByDateAndVar1 = 
    yourList.stream()
        .collect(Collectors.groupingBy(
            ObjectA::getTime, 
            Collectors.groupingBy(ObjectA::getVar1)));

This assumes ObjectA has also a getVar1 method.

Finally, if you need to group by a third nested criteria, you could do it in a similar way:

Map<Date, Map<String, Map<String, List<ObjectA>>>> groupsByDateAndVar1AndVar2 = 
    yourList.stream()
        .collect(Collectors.groupingBy(
            ObjectA::getTime, 
            Collectors.groupingBy(
                ObjectA::getVar1,
                Collectors.groupingBy(ObjectA::getVar2))));

This assumes ObjectA has also a getVar2 method.

Upvotes: 1

Ben Arnao
Ben Arnao

Reputation: 543

a List<List<Object>> is probably what you want if you want to group by the first variable and then subgroup by the second

You could also do a Tree, up to you

Upvotes: 0

osanger
osanger

Reputation: 2352

This is an example of a simple tree structure for your problem.

public class Tree {

private Node root;

public Tree(List<YourObject> rootData) {
    root = new Node();
    root.data = rootData;
    root.children = new ArrayList<Node>();
}

public static class Node {
    private List<YourObject> data;
    private Node parent;
    private List<Node> children;
}
}

Your can build a simple tree and run all tree and graph-algorithms on this simple structure.

Upvotes: 2

Related Questions