1

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.

15
  • Why do you wish to avoid nested loops in this case? Complexity? Commented Apr 6, 2013 at 11:17
  • 5
    Why do you need such a structure, ArrayList of ArrayList, if you want to access it as though it was flat anyway? Commented Apr 6, 2013 at 11:21
  • 1
    You could have both : the list of lists you have now, AND another list containing all the elements of all the lists. Commented Apr 6, 2013 at 11:26
  • 2
    @JavaCake instead of passing say, 4, pass 3,5. 3 being the index of the arraylist, and 5 being the index inside that arraylist. Commented Apr 6, 2013 at 11:28
  • 2
    I don't see how it's messy. Encapsulate that into a class. Commented Apr 6, 2013 at 11:28

3 Answers 3

2

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"
}
Sign up to request clarification or add additional context in comments.

Comments

0

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));
    }
}

Comments

0
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);
 }
}

1 Comment

The second ArrayList in the area statement should be List. The generic types must be identical. But in Java 7, just use <>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.