Implementing Generic Collection?

BlitzMax Forums/BlitzMax Programming/Implementing Generic Collection?

zoqfotpik(Posted 2014) [#1]
I'd like to set up an arraylist type. I know that to do that you have to have your internal structure be of type Object.

But I run into two issues with that.

First, how do you get an object from the list? When I do that, I can't cast from type Object (Unable to Convert from Object to <Whatever.>)

Second, how do you trigger a method on an object in the arraylist? Array[i].<whatever> gets "Identifier whatever not found."

Ideas?

I could just use someone else's but I'm really trying to understand this.

' Collection Test

' Implementing Array List

Type JTArrayList
Field internalarray:Object[1000]
Field index:Int

Method Addlast:TLink(value:Object)
	i = i + 1
	internalarray[i] = value
End Method

Method dump()
	For i = 0 To internalarray.length
	internalarray[i].dump
	Next
End Method

Method getbyindex:Object(index:Int)
	If index < 1 Or index > 1000 ' Yes, I understand why we don't do this sort of thing
 		Return Null
	Else
		Return internalarray[index]
	EndIf
End Method
End Type

test:JTArrayList = New JTArrayList

Type boxint
Field a:Int
Method dump()
Print a
End Method
End Type

a:boxint = New boxint
test.addlast(a)
test.dump()

b:boxint = New boxint
'b=test.getbyindex(1)
'b.dump()



Yasha(Posted 2014) [#2]
I can't cast from type Object (Unable to Convert from Object to <Whatever.>)


Downcasts need to be explicit:

b=test.getbyindex(1)    'wrong
internalarray[i].dump

b = boxint(test.getByIndex(1))    'should work
boxint(internalarray[i]).dump


Note that if your collection specifically demands that its contained values have a specific method such as `dump`, there's not a whole lot of point in it storing Objects (you'll just get null reference crashes when you try to call the method on Null, if anything else is in the list). You should require that it store a objects of a type fulfilling the needed interface (i.e. that all stored objects extend Dumpable).

The alternative - and the closest you can get in pure Max to something that doesn't clog up your inheritance tree - is to use Object.SendMessage. This won't stop other objects from being stored, but they shouldn't do anything harmful because by default SendMessage does nothing. Your element types just have to implement Dump as a message instead of (or as well as) a method.


(While you're also welcome to use my Interfaces extension as a third option, be warned that it's intended for the official compiler, and won't work with 64-bit or non-x86 targets on Brucey's.)


zoqfotpik(Posted 2014) [#3]
Downcasts need to be explicit:

Ah, I thought of that and then I thought "No, that would only work for built-in types."

I understand what you're saying about interfaces as well, that makes sense. I'm going to be setting up a map for indexes (so I can do inserts without all manner of updating references) and I can just use that for message passing.

Thanks!

I may just not implement it as a generic at all, I guess it doesn't really HAVE to be.