Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (121)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Java Generic problems.  (Read 3343 times)
0 Members and 1 Guest are viewing this topic.
Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Posted 2012-07-12 19:43:47 »

To keep it short:
I've got this method:
1  
public void query([...], List<QuadtreeElement /*, which is an interface */> results) { [...] }


And I want to call it like that:
1  
2  
ArrayList<Element /*, which implements QuadtreeElement*/> list = new ArrayList<Element>();
tree.query([...], list);


The problem/error that I get is this one:
Quote
The method query([...], List<QuadtreeElement>) in the type Quadtree is not applicable for the arguments ([...], ArrayList<Quadtree.Elem>)

I also tried:
1  
public void query([...], List<E extends QuadtreeElement> result) { [...] }


But this throws this error:
Quote
Syntax error on token "extends", , expected

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline sproingie

JGO Kernel


Medals: 202



« Reply #1 - Posted 2012-07-12 19:52:51 »

They're called generics, not templates.   Expecting C++ template-like behavior will lead to heartbreak.  Anyway, you're 99% of the way there -- you just need to replace 'E' with '?' so you end up with:

1  
public void query([...], List<? extends QuadtreeElement> result) { [...] }


http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Offline Danny02
« Reply #2 - Posted 2012-07-12 20:11:41 »

just a quick question about what you do with this "result" collection.

Do you fill it with elements in your querry method?
If I think it is not the good of a idea, beside then you should use an upper and not a lower bound. ? super CLASS instead of ? extends CLASS
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproingie

JGO Kernel


Medals: 202



« Reply #3 - Posted 2012-07-12 21:44:23 »

Good catch.  If query can only return QuadtreeElement, you can't make it fill a List<Element> any more than a method returning Object can populate a String variable.  Obviously if your query is actually getting Element instances, you can downcast them, but it's not a terribly good idea.

This thread does an amazing job at explaining it: http://stackoverflow.com/questions/591004/generics-super-t

The choice of names is really confusing BTW, because it looks like Element should be the interface and QuadtreeElement the implementation.
Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #4 - Posted 2012-07-13 11:58:21 »

Mhmmm... so I tried this out:

1  
public void query([...], List<? extends QuadtreeElement> results) { [...] }


Which didn'nt work. It gave me this error on a later "results.add([QuadtreeElement])" (The problem is, that I don't know which QuadtreeElement implementing class is actually is:
Quote
The method add(capture#1-of ? extends QuadtreeElement) in the type List<capture#1-of ? extends QuadtreeElement> is not applicable for the arguments (QuadtreeElement)

The problem on the later call of "query" didn't throw any errors.

So I changed it to:
1  
public void query([...], List<? super QuadtreeElement> results) { [...] }


So now the Error on the "results.add([QuadtreeElement])" is gone, but the error on the "tree.query([...], [ArrayList])" is back:
Quote
The method query(StaticRect, List<? super QuadtreeElement>) in the type Quadtree is not applicable for the arguments (StaticRect, ArrayList<Quadtree.Element/*Mind that there is the dot*/>)

Also, since this might be helpful, here is the almost-complete source-code:
[Offtopic: Riven, the pastbin seems to be broken:
"8: Undefined variable: seek
File: /home/jgo/public_html/addon_pastebin.php
Line: 12"
So I just post it as normal pastebin:]
http://pastebin.com/C0RsHqip

I need help... :/

The problem with using "Quadtree<E extends QuadtreeElement>" is, that this would not be working:
1  
elements = new E[elemPerQuad]; // See in the constructor


I hope you can help me Smiley

EDIT:
just a quick question about what you do with this "result" collection.

Do you fill it with elements in your querry method?
If I think it is not the good of a idea, beside then you should use an upper and not a lower bound. ? super CLASS instead of ? extends CLASS
Yes I do fill it with "results.add([QuadtreeElement])"...

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #5 - Posted 2012-07-13 12:24:54 »

Ooookey. I fixed it. JGO's pastebin is still not working for me...
The source code will be posted on "Shared Code" Smiley
(Editing link into it, for everyone googleing this.)
EDIT:
The Topic

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline sproingie

JGO Kernel


Medals: 202



« Reply #6 - Posted 2012-07-13 15:53:02 »

1  
elements = new E[elemPerQuad]; // See in the constructor


Can't be done.  Anything that needs the type of E at runtime is impossible.  In this one case, it's easily fixed, just change elements to List<E>.  Other cases where you need something like 'new E' you're out of luck

http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html#2.0

Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #7 - Posted 2012-07-13 16:16:36 »

1  
elements = new E[elemPerQuad]; // See in the constructor


Can't be done.  Anything that needs the type of E at runtime is impossible.  In this one case, it's easily fixed, just change elements to List<E>.  Other cases where you need something like 'new E' you're out of luck

http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html#2.0

I solved it by using
1  
elements = (E[])(new QuadtreeElement[elementsPerQuad]); // suppressing a warning here :)

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Gudradain
« Reply #8 - Posted 2012-07-13 16:42:51 »

I solved it by using
1  
elements = (E[])(new QuadtreeElement[elementsPerQuad]); // suppressing a warning here :)


Does it even makes sense?
Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #9 - Posted 2012-07-13 16:43:41 »

I solved it by using
1  
elements = (E[])(new QuadtreeElement[elementsPerQuad]); // suppressing a warning here :)


Does it even makes sense?
Yes.
EDIT: Detailed question. Detailed answer Wink

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Gudradain
« Reply #10 - Posted 2012-07-13 16:45:57 »

Sorry I don't see why...

I mean you can do the following :

1  
List list = new ArrayList();


but you can't do it the other way around

1  
ArrayList list = new List(); //Don't tell me you can't instanciate List directly, I know...


but I need to add that the following can make sense

1  
ArrayList list = (ArrayList) listInstance; //Will work if listInstance was already an instance of ArrayList

Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #11 - Posted 2012-07-13 16:54:59 »

Sorry I don't see why...

I mean you can do the following :

1  
List list = new ArrayList();


but you can't do it the other way around

1  
ArrayList list = new List(); //Don't tell me you can't instanciate List directly, I know...


but I need to add that the following can make sense

1  
ArrayList list = (ArrayList) listInstance; //Will work if listInstance was already an instance of ArrayList



I did that because, just as sproingie said:
1  
elements = new E[elemPerQuad]; // See in the constructor


Can't be done.

So I did a workaround.
I casted a newly-created Array to the specified chosen "E"-Array. I can be sure, that E extends QuadtreeElement, so I choose it. I could have also used Object, that was just for readablility.

You could try it out yourself: use QuadtreeElement[] yourself. You will get an error, because you can't assign a QuadtreeElement[] to E[]. So you need to cast that array to E[].

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Gudradain
« Reply #12 - Posted 2012-07-13 17:05:11 »

1  
(ArrayList) new List();

Is not equal to
1  
new ArrayList()


That's basically what you seems to be trying to do here with
1  
elements = (E[])(new QuadtreeElement[elementsPerQuad]); // suppressing a warning here :)

Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #13 - Posted 2012-07-13 17:08:29 »

1  
(ArrayList) new List();

Is not equal to
1  
new ArrayList()


That's basically what you seems to be trying to do here with
1  
elements = (E[])(new QuadtreeElement[elementsPerQuad]); // suppressing a warning here :)


Yes but objects are still different from Arrays. In the end I'm casting ints to ints or longs to longs and only change the "mark", which type of class is used for this Array.
What I can tell you is: it does not work without this workaround. This workaround is solid, and works for every case Wink

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Gudradain
« Reply #14 - Posted 2012-07-13 17:17:15 »

Yes but objects are still different from Arrays. In the end I'm casting ints to ints or longs to longs and only change the "mark", which type of class is used for this Array.
What I can tell you is: it does not work without this workaround. This workaround is solid, and works for every case Wink

Strange when I try to run the following code in eclipse it crash :
1  
2  
3  
4  
5  
6  
7  
public class TypeArray {
   
   public static void main(String [] args){
      String[] array = (String[]) (new Object[10]);
   }

}


with that exception
1  
2  
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
   at test.TypeArray.main(TypeArray.java:6)


Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2012-07-13 17:30:53 »

Because an Object is not a String, but the other way around is true:

1  
Object[] array = (Object[]) new String[10];

Offline davedes
« Reply #16 - Posted 2012-07-13 17:34:42 »

To get a String array from an Object array, you'd need to do something like this:
1  
2  
3  
4  
String[] s = new String[other.length];
for (int i=0; i<other.length; i++) {
    s[i] = other[i]!=null ? other[i].toString() : null;
}


Though generally speaking you'll never need to deal with the Object class if you use generics wisely. Smiley

EDIT: I sorta jumped in instead of reading the thread. But I'll leave this here, anyways...

Offline Gudradain
« Reply #17 - Posted 2012-07-13 17:42:13 »

Guys I know full well that Object is not a String, if you read the thread carefully you will see that I'm trying to help Matheus23.

Am-I the only one that see something really strange in his code?

Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #18 - Posted 2012-07-13 17:45:24 »

Guys I know full well that Object is not a String, if you read the thread carefully you will see that I'm trying to help Matheus23.

Am-I the only one that see something really strange in his code?
Actually I don't have any problems now. They are all solved.
That code I wrote gives me a warning, but it actually can't crash, so why bother?

Also, thank you for trying to help me, but currently you only said, that that code part didn't make sense, and why. You didn't even give me another option, or an Idea of how to do it another way.

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline davedes
« Reply #19 - Posted 2012-07-13 18:15:05 »

1  
elements = (E[])(new QuadtreeElement[elemPerQuad]);



How about this?
1  
List<E> elements = new ArrayList<E>(elemPerQuad);

Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #20 - Posted 2012-07-13 18:25:30 »

I suggested using ArrayList in his QuadTree thread too. It's superior to using arrays.

Offline matheus23

JGO Kernel


Medals: 109
Projects: 3


You think about my Avatar right now!


« Reply #21 - Posted 2012-07-13 18:31:54 »

Yes, this could be an option. But the problem is, that I want to use as low memory as possible, and as I have fixed-size elements per quad anyways, I don't need lists.

(Also Lists do almost the same hack I do internally... They use an Object[] and then cast the elements to (E).)

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Gudradain
« Reply #22 - Posted 2012-07-13 19:10:46 »

Let put it all together...

First, you asked for that :

And I want to call it like that:
1  
2  
ArrayList<Element /*, which implements QuadtreeElement*/> list = new ArrayList<Element>();
tree.query([...], list);


Then you show the code and we can see that :
1  
 public void query(StaticRect range, List<? super QuadtreeElement> results) {


Which probably don't do the thing you want to do since you asked for calling it for any subclass of QuadtreeElements and now it call it for any superclass of QuadtreeElements...

What you really wanted to do is probably that :

1  
2  
3  
public class Quadtree<E extends QuadtreeElement>{
    public void query(StaticRect range, List<E> results){}
}


or

1  
public <E extends QuadtreeElement> void query(StaticRect range, List<E> results){}
Offline davedes
« Reply #23 - Posted 2012-07-13 20:09:18 »

Yes, this could be an option. But the problem is, that I want to use as low memory as possible, and as I have fixed-size elements per quad anyways, I don't need lists.
The memory difference is extremely negligible in this case - a few Objects vs. a few arrays.

This is a perfect example of "premature optimization" -- introducing ugly hacks as a means of optimizing, when in reality it will make zero noticeable difference in memory/performance.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

theagentd (16 views)
2014-10-25 15:46:29

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (45 views)
2014-10-16 15:22:06

Norakomi (34 views)
2014-10-16 15:20:20

lcass (39 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (74 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!