You did not specify much about the interface, so I'll just define some basics from which you could go on and develop more:
You could go on and define an iterator, implement various collection interfaces and whatever you want.
Note that any client code should not be concerned about implementation details. Carefully think about the interface of your list with blocked width. The interface tells the client everything it needs to now. How the interface is implemented is solely the concern of the implementing class. That said, you can easily store your two-dimensional list with blocked-width as a single, plain java.util.List
. But hide that list from your clients.
Here's the code I propose:
public class BlockedWidthList<T> {
public static void main(String[] args) {
BlockedWidthList<Integer> myList = new BlockedWidthList<Integer>(6);
for(int i = 0; i < 20; i++)
myList.add(i);
for(Integer entry : myList.getRow(2))
System.out.println(entry);
}
/** @throws java.lang.IllegalArgumentException if 'blockedWidthSize' is less than or equal to zero */
public BlockedWidthList(int blockedWidthSize){
if(blockedWidthSize<1)
throw new IllegalArgumentException("Width must be a positive number");
this.blockedWidthSize = blockedWidthSize;
}
public final int blockedWidthSize;
private List<T> internal = new ArrayList<T>();
public void add(T elem){
internal.add(elem);
}
/** Access a row in the blocked width list by a row index. Indexing starts at 0
*
* @return A list containing up to 'blockedWidthSize' elements
* @throws java.lang.IndexOutOfBoundsException if the row does not exist
*/
public List<T> getRow(int rowIndex){
if (rowIndex < 0) throw new IndexOutOfBoundsException("Negative row");
int startIdx = rowIndex * blockedWidthSize;
return internal.subList(startIdx, startIdx + blockedWidthSize);
}
}
You can see that, under the hood, this class only uses a list and an integer. Add
simply forwards the call to the underlying list.
The method you are probably interested in is getRow
. Let's think about where the i
th row can be found in the list.
The first row is always at index 0, since we are appending elements at the end.
The second row starts after removing blockWidthSize
number of elements. Since we are 0 indexed, the second row starts at index blockWidthSize
If you think about it, the first element of the i
th row is at index i * blockWidthSize
.
We then simply return the subList
starting at the computed index and ending blockedWidthSize
elements later.
Edit: Obviously, this interface is fairly useless: A client can not know whether he can access a certain row unless he either knows all elements that were put into the list, or if he catches the exception thrown when accessing an invalid row. This means, in the minimum you should add a method to the interface that exposes information about the size of the list. This could simply be the number of elements (i.e., forwarding a call to internal.size()
, or the number of rows (which requirs some computations, but is not too hard to do)