JavaCake
JavaCake

Reputation: 4115

Accessing ArrayList<ArrayList<SomeObject>> elements

I have an ArrayList of ArrayLists where I need to find a simple way of accessing the elements. To make it easier to understand, I have drawn my goal of what I want to achieve:

enter image description here

As seen on the image above the main ArrayList consists of m ArrayList, where I wish to get an element by using a get method which goes from 0 to N elements, where N is the total elements of ArrayList1 and ArrayList2. More ArrayLists may occur.

I can, of course, iterate through the elements by using two for-loops, that is not what I'm searching for in this case.

Upvotes: 1

Views: 776

Answers (3)

Roman C
Roman C

Reputation: 1

class Plot {
 class Point {
   int x;
   int y;
 }

 List<List<Point>> area = new ArrayList<List<Point>>();

 Point getPoint (int x, int y) throws IndexOutOfBoundsException {
   if (x < 0 && x >= area.size())
     throw new IndexOutOfBoundsException();
   int l = area.get(x).size();
   int i = (int)y/l;
   int j = y % l;
   return area.get(x+i).get(j);
 }

 void setPoint (int x, int y, Point p) throws IndexOutOfBoundsException {
   if (x < 0 && x >= area.size())
     throw new IndexOutOfBoundsException();
   int l = area.get(x).size();
   int i = (int)y/l;
   int j = y % l;
   area.get(x+i).set(j, p);
 }
}

Upvotes: 0

Daniel Imms
Daniel Imms

Reputation: 50229

You would need to basically have the the ArrayList members on your new wrapper class and implement them in a different manner. I whipped up an example that demonstrates the correct index being calculated in get().

import java.util.ArrayList;

public class ListHolder<T> {
    public ArrayList<ArrayList<T>> list = new ArrayList<ArrayList<T>>();

    public int size() {
        int size = 0;
        for (int i = 0; i < list.size(); i++) {
            size += list.get(i).size();
        }
        return size;
    }

    public T get(int i) {
        if (i >= size())
            return null;

        int listIndex = 0;
        int valueIndex = i;

        while (valueIndex >= list.get(listIndex).size()) {
            valueIndex -= list.get(listIndex++).size();
        }

        return list.get(listIndex).get(valueIndex);
    }
}

What I used to verify my methods:

public static void main(String[] args)
{
    ListHolder<Object> listHolder = new ListHolder<Object>();

    listHolder.list.add(new ArrayList<Object>());
    listHolder.list.get(0).add("hello");
    listHolder.list.get(0).add("world");

    listHolder.list.add(new ArrayList<Object>());
    listHolder.list.get(1).add("a");
    listHolder.list.get(1).add("b");
    listHolder.list.get(1).add("c");

    System.out.println("Size: " + listHolder.size());
    System.out.println("listHolder[0]: " + listHolder.get(0)); // "hello"
    System.out.println("listHolder[1]: " + listHolder.get(1)); // "world"
    System.out.println("listHolder[2]: " + listHolder.get(2)); // "a"
    System.out.println("listHolder[3]: " + listHolder.get(3)); // "b"
    System.out.println("listHolder[4]: " + listHolder.get(4)); // "c"
    System.out.println("listHolder[5]: " + listHolder.get(5)); // "null"
}

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 692023

You don't provide many details about what these lists are, and if they're mutable or not. But you could probably use an additional list containing all the elements of all the sublists:

private class Generation
    private List<List<Element>> populations = new ArrayList<>();
    private List<Element> allElements = new ArrayList<>();

    public Element getElementAt(int elementIndex) {
        return allElements.get(elementIndex);
    }

    public void addPopulation(List<Element> population) {
        populations.add(new ArrayList<>(population));
        allElements.addAll(population);
    }

    public List<Element> getPopulationAt(int populationIndex) {
        return Collections.unmodifiableList(populations.get(populationIndex));
    }
}

Upvotes: 0

Related Questions