• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to create Generic 2-dimensional array?

 
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm trying to convert an original int-based Matrix class into a generic Matrix class. The int-based code contains this initializer:




However, when I try to convert it to a generic format, I run into problems:



I've already google this a bit and have learned that for the sake of backward-compatibility, Java doesn't support generic arrays. I've found suggestions to use Array.newInstance, but I can't get find the right permutation of the code to make it work; e.g.:



There are MULTIPLE references to an article by Neal Gafter at the Sun site throughout the web (even elsewhere here at this site), BUT THAT LINK IS DEAD, so I can't access what might be the golden article I need.

If anyone can help me construct the correct equivalent code for:



...using generics, I'd be much obliged.

Many thanks!
 
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are two ways to solve this:
1) data = (T[][])new Object[rows][columns];
2) declare data as an Object[][], then cast to T when retrieving elements from the matrix.

Yes, both will generate compiler warnings (note: warnings, not errors). That's because the compiler can no longer verify that the data is going to be correct. Both solutions will lead to errors if some other code puts a non-T into the array. Keep data private and you get to control that, thereby making the warned cast safe and therefore ignorable.

For your info, ArrayList uses the second approach.
 
Tom Brodhead
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sadly, the nice-looking suggestion:

data = (T[][])new Object[rows][columns];

...does not work; I can't run the example code with that modification without getting "Unresolved compilation problems".

Eclipse has this info about the problem with that code:

Multiple markers at this line
- Type mismatch: cannot convert from T to int
- Type safety: Unchecked cast from Object[][]
to T[][]
- Type mismatch: cannot convert from T to int


"rows" and "columns" get red squiggly underlines.

 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1) Shouldn't rows and columns still be ints? Those are the dimensions, not matrix elements.
2) The unchecked cast is a warning, not an error. I warned you about that. To prevent this warning (if you've ensured that all access to it is safe and secured) you can use @SuppressWarnings:
 
Tom Brodhead
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah! Thank you! I'm closer now, but I've run into a problem in the next step, adding together two matrices.

I'm not clear on how to cast references to the arrays for arithmetic operations; the IDE complains:

The operator + is undefined for the argument type(s) java.lang.Object, java.lang.Object

How do I reference the generic type that being employed? I've tried pre-pending (T) before each array reference, but it doesn't work. Here's my code:



Also, am I right to use <?> when the type isn't known?
 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tom Brodhead wrote:I'm not clear on how to cast references to the arrays for arithmetic operations; the IDE complains:

The operator + is undefined for the argument type(s) java.lang.Object, java.lang.Object

How do I reference the generic type that being employed? I've tried pre-pending (T) before each array reference, but it doesn't work.


+ is only available for Strings and the numeric primitive types (including char) (and their wrappers because of auto unboxing). For anything else you'll need to use methods. In this case you have two options:
1) use a common interface with a method for adding. You must then limit T to that interface. That excludes existing classes like Integer, Long and Double though.
2) use a set of interfaces for the operations. Your add method then also takes an instance of such an interface.
For example:
Granted, it's not nice looking, but at least you'll be able to use Integer etc.

Also, am I right to use <?> when the type isn't known?


Right. But you don't want that in this method, because you don't want to add an apple matrix to a pear matrix, do you? You want to at least limit them to some common type; that's what T is in my code. Note that this T is different from the class generic type.
 
Tom Brodhead
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow, thanks! However, the IDE underlines the word "add" in this line:



...and produces the following error code:

The method add(T, T) in the type Addition<T> is not applicable for the arguments (Object, Object)

I'm also confused by the syntax in the add method signature:



Are you casting a GenericMatrix<T> as type <T>?

Finally, I'm not clear how I would call this method. For generic matrices A and B, this command produces a slew of error messages:



(Inserting <Integer> into the command in different locations produced no reduction of error messages.)

Somehow I feel I'm well out of my water in trying to tackle this seemingly straightforward problem, or else my luck has brought me to one of the thornier issues of Java programming. It seems like there are a lot of subtleties here that I'm not grasping...

Thanks in advance for your help!

 
reply
    Bookmark Topic Watch Topic
  • New Topic