Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Triple-Nested ArrayList Peculiarity  RSS feed

 
Julian West
Ranch Hand
Posts: 91
3
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello.

I'm a bit stumped--easy to do since I've only been at this a few months--but this seems inconsistent and I can't find anything beyond double-nested Lists.

Problem: Compiler recognises ArrayList<String> as an Object when nested in an ArrayList<List> that is nested in another ArrayList<List>.  I don't have ArrayList methods (like get(int i)), only Object methods.  To get around this, I had to explicitly cast the ArrayList<String> element.  Building it works, printing it works, only getting the Strings out is the problem.

Westenstein's Monster

Filling the Lists (works):

Dumping the lists (works):

What doesn't work (xxxx = Object methods, not List methods) and compiling with the .get operator yields "java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: <any>"

Workaround:

The workaround is quite tedious (and I really don't like workarounds) and I don't really want to be ambushed later with more quirkiness that may prompt starting over.  More importantly, I want to understand this and what I'm doing wrong or what limitation I've hit. 

(What I'm doing is extrapolating data contained in the HTML tables on my cable modem's status pages and will plug them into object properties; the nested lists contain tables, rows, and data cells.)

What am I missing here? 

Thank you for any insight in advance.

-jw
 
Carey Brown
Bartender
Posts: 2994
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This definition is incomplete
List<List> tableList = new ArrayList<>()
You need something like
List<List<List<String>>> tableList = new ArrayList<>()
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try to change the return type of method as - List < List < List < String > > >  ----> this is your tablelist,you have just declare that list is holding List type objects but not mention what actually did the inner list is carrying,so compiler simply thinks its a object.
inside the method change the type parameter of rowlist as List < List < String >>,again you have not mention what actually is the nested List Holding.

Hope this will help!

Kind Regards,
praveen.
 
Julian West
Ranch Hand
Posts: 91
3
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
AAAAaaaaoooooooohhhhhhkay! I see now.  I was thinking [][][] (array-like syntax, sequential) for lists which are actually nested in syntax: <<<>>>.  Whew! 
I think this lesson will stick.
Thank you!

Proper working code:


 
Piet Souris
Rancher
Posts: 1980
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What I sometimes do when dealing with trply (or higher) nested Lists is to define some intermediate classes, to keep things manageable.
For instance: I could make a class 'Table extends List<String>', a class 'TableCollection extends List<Table>', et cetera, dearly missing Scala's 'type' here.
All you need then is to define a minimal number of suitable constructors. But it enables you to do things like:
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you use the concept of an array, its elements are arrays of the type specified. String[][][] is an array of arrays of Strings. There is no other syntax which doesn't say String.
But if you write List<List<List>>> you have never said you are putting Strings in anywhere.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:For instance: I could make a class 'Table extends List<String>', a class 'TableCollection extends List<Table>', et cetera...

Hmmm. Seems a bit odd to me.
1. Your Table definition is simply a List<String>, so all you're doing is fixing the element type.

2. The only advantage I could see with TableCollection would be if it was defined as something like
  public class TableCollection<E> extends ArrayList<List<E>> implements Iterable<E> ...
ie, something that takes the drudge out of returning the elements of an embedded level.

And TBH, I suspect that it might actually lend itself more to an embedded Map structure...depending on what you want to do with it of course.

Winston
 
Piet Souris
Rancher
Posts: 1980
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
well, I don't want to hijack this topic, but in short:

I don't bother about a generic version, too much trouble. A while ago I was working on a KillerSudoku program, and I was faced with the task of saving and loading a puzzle. Now, I have my Tuple<K, V> class, and I ended up with this method:

(Liutauras just taught me to use Path instead of File, btw). But next day I looked again at this method, couldn't believe my eyes. And using some intermediate classes made all the difference for me. Anyway, there might be better ways, like you write, and maybe it is a bad idea alltogether. But I liked it.
 
Julian West
Ranch Hand
Posts: 91
3
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:If you use the concept of an array, its elements are arrays of the type specified. String[][][] is an array of arrays of Strings. There is no other syntax which doesn't say String.
But if you write List<List<List>>> you have never said you are putting Strings in anywhere.


I never used nested <<<>>>; I only nested the objects, not the references--my epiphany here.

I created/filled List<List>, then inside that, I created/stuffed List<List> into the outer List, then inside that, I created/stuffed List<String> inside that.  This only works when unravelling (deliberately avoiding the word, "unwrapping") in the same way: nested loops to get() the elements but not using the outermost object reference since it has no knowledge of what's inside beyond itself.

A visual--and this is my pre-OOP thinking here--is like we said: String[][][] works for arrays but List<List>List<List>List<String> (a visual of what I did with loops) doesn't work for ArrayLists as the generics have to be nested as well. 

// Insert Star Trek II movie clip of Spock pointing out Khan's 2-dimensional thinking
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Julian West wrote:. . . Insert Star Trek II movie clip of Spock pointing out Khan's 2-dimensional thinking
But Spock could not cope with thinking in as few as two dimensions.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!