Wrapping primitive types in arrays

S

Simone

Hello,

I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ). The numbers can be int or double and I wish to
write only one method for both types so, remembering that Java wraps
primitive types into their corresponding objects (int in Integer,
double in Double) I wrote a method:

public String print( Number[] data ){ ... }

When I try to invoke the print method with an int[] or a double[]
argument, I get an error:

"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"

Actually, I expected Java would have wrapped the int[] into Integer[],
just as it wraps an int into an Integer. Since I can assign an
Integer[] to a Number[] I thought that by wrapping int into Integer,
Java would have allowed me to assign an int[] to a Number[]. Even if I
try to cast (i.e. trying to print( (Integer[])data ) ), Java says it
"Cannot cast from int[] to Integer[]".

Is there a way to fix this? Or I need to migrate all my int[] and
double[] in Integer[] and Double[]?

Many thanks in advance.
 
J

Jean-Baptiste Nizet

Hello,

I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ).

So, you want to reimplement java.util.Arrays.toString(int[]) and
java.util.Arrays.toString(double[]). Why don't you use the already
available and standard methods?
The numbers can be int or double and I wish to
write only one method for both types so, remembering that Java wraps
primitive types into their corresponding objects (int in Integer,
double in Double) I wrote a method:

public String print( Number[] data ){ ... }

Transforming each and every primitive int or double of a (potentially)
huge array into its counterpart object just to print them sounds like
a bad idea to me. Why don't you want two overloaded methods, just as
in java.util.Arrays?
When I try to invoke the print method with an int[] or a double[]
argument, I get an error:

"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"

Actually, I expected Java would have wrapped the int[] into Integer[],
just as it wraps an int into an Integer. Since I can assign an
Integer[] to a Number[] I thought that by wrapping int into Integer,
Java would have allowed me to assign an int[] to a Number[]. Even if I
try to cast (i.e. trying to print( (Integer[])data ) ), Java says it
"Cannot cast from int[] to Integer[]".

Your expectation was thus wrong.
Is there a way to fix this? Or I need to migrate all my int[] and
double[] in Integer[] and Double[]?

You won't migrate all your primitive arrays into object arrays just to
be able to call a single print method instead of two, won't you? Just
use two separate and ad hoc methods to print your two different kinds
of arrays.
 
S

Sebastian Millies

Am 04.10.2010 12:52, schrieb Simone:
[snip]
Actually, I expected Java would have wrapped the int[] into Integer[],
just as it wraps an int into an Integer. Since I can assign an
[snip

no, Java cannot autobox arrays. You'll have to do the boxing yourself.

The following is copied from a post in
http://forums.sun.com/thread.jspa?threadID=532625&messageID=2571860


/**
* Copy an array to another array.
* <br>
* arraycopy(int[], Integer[]) <br>
* arraycopy(int[], int[]) <br>
* arraycopy(Integer[], Integer[]) <br>
* arraycopy(Integer[], int[])
*/
public static void arraycopy( Object srcArray, Object destArray )
{
if( !srcArray.getClass().isArray() || !destArray.getClass().isArray()
|| Array.getLength( destArray ) != Array.getLength( srcArray ) ) {
throw new IllegalArgumentException( "Cannot copy array!" );
}

int len = Array.getLength( srcArray );

for( int i = 0; i < len; i++ ) {
Array.set( destArray, i, Array.get( srcArray, i ) );
}
}

-- Sebastian
 
J

John B. Matthews

Simone said:
I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ). The numbers can be int or double and I wish to
write only one method for both types so, remembering that Java wraps
primitive types into their corresponding objects (int in Integer,
double in Double) I wrote a method:

public String print( Number[] data ){ ... }

When I try to invoke the print method with an int[] or a double[]
argument, I get an error:

"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"

Actually, I expected Java would have wrapped the int[] into
Integer[], just as it wraps an int into an Integer. Since I can
assign an Integer[] to a Number[] I thought that by wrapping int into
Integer, Java would have allowed me to assign an int[] to a Number[].
Even if I try to cast (i.e. trying to print( (Integer[])data ) ),
Java says it "Cannot cast from int[] to Integer[]".

Is there a way to fix this? Or I need to migrate all my int[] and
double[] in Integer[] and Double[]?

You might be able to use the toString() methods of java.util.Arrays:

<http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html>
 
S

Simone

 Simone said:
I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ). The numbers can be int or double and I wish to
write only one method for both types so, remembering that Java wraps
primitive types into their corresponding objects (int in Integer,
double in Double) I wrote a method:
public String print( Number[] data ){ ... }
When I try to invoke the print method with an int[] or a double[]
argument, I get an error:
"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"
Actually, I expected Java would have wrapped the int[] into
Integer[], just as it wraps an int into an Integer. Since I can
assign an Integer[] to a Number[] I thought that by wrapping int into
Integer, Java would have allowed me to assign an int[] to a Number[].
Even if I try to cast (i.e. trying to print( (Integer[])data ) ),
Java says it "Cannot cast from int[] to Integer[]".
Is there a way to fix this? Or I need to migrate all my int[] and
double[] in Integer[] and Double[]?

You might be able to use the toString() methods of java.util.Arrays:

<http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html>

First of all, thanks to you all for answering.

In my previous post I omitted some details because I didn't want to
bother you with unnecessary details (but maybe they were necessary): I
tried to use the Number[] type in the argument of print() function
because I cannot know what will be the actual type (int[] or double[])
until run-time.

This method is part of a generic class parameterized by <N extends
Number> because it must work with integer numbers or real numbers.
The class contains various fields, one of them is a N[] array. The
constructor is:

public Result( N[] data, ...etc... )

The constructor assigns the parameter data to the corresponding field
of the class.
The method print is no more relevant (I refactored the method
meanwhile, now it has no parameters), but when I test my class trying
to invoke the constructor with:

Result<Integer> res = new Result<Integer>( intArray, ...etc... );
(intArray is an int[])

I get the error for which the constructor
Result<Integer>( int[], ...etc...) is undefined.
If I change the type of intArray from int[] to Integer[], it works.
This is the reason why I asked if I had to substitute all the int[]
and double[] with their corresponding wrapper classes.

I apologize for being unclear previously.


Simone.
 
M

markspace

If I change the type of intArray from int[] to Integer[], it works.
I apologize for being unclear previously.


This is even more unclear to me because the first statement is untrue.
I just tested passing an int[] to a method requiring Integer[]
("method(Integer[] a)"). It does not work.

Look at your code again, I don't think it's doing what you think it's doing.
 
C

chankey pathak

Hello,

I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ). The numbers can be int or double and I wish to
write only one method for both types so, remembering that Java wraps
primitive types into their corresponding objects (int in Integer,
double in Double) I wrote a method:

public String print( Number[] data ){ ... }

When I try to invoke the print method with an int[] or a double[]
argument, I get an error:

"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"

Actually, I expected Java would have wrapped the int[] into Integer[],
just as it wraps an int into an Integer. Since I can assign an
Integer[] to a Number[] I thought that by wrapping int into Integer,
Java would have allowed me to assign an int[] to a Number[]. Even if I
try to cast (i.e. trying to print( (Integer[])data ) ), Java says it
"Cannot cast from int[] to Integer[]".

Is there a way to fix this? Or I need to migrate all my int[] and
double[] in Integer[] and Double[]?

Many thanks in advance.

Why don't you use java.util.Arrays.toString(arguments) ?
Do you have any problem with that? Use it man, they were written to be
used in situations like this.
 
S

Simone

I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ). The numbers can be int or double and I wish to
write only one method for both types so, remembering that Java wraps
primitive types into their corresponding objects (int in Integer,
double in Double) I wrote a method:
public String print( Number[] data ){ ... }
When I try to invoke the print method with an int[] or a double[]
argument, I get an error:
"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"
Actually, I expected Java would have wrapped the int[] into Integer[],
just as it wraps an int into an Integer. Since I can assign an
Integer[] to a Number[] I thought that by wrapping int into Integer,
Java would have allowed me to assign an int[] to a Number[]. Even if I
try to cast (i.e. trying to print( (Integer[])data ) ), Java says it
"Cannot cast from int[] to Integer[]".
Is there a way to fix this? Or I need to migrate all my int[] and
double[] in Integer[] and Double[]?
Many thanks in advance.

Why don't you use java.util.Arrays.toString(arguments) ?
Do you have any problem with that? Use it man, they were written to be
used in situations like this.

@ rossum: I tried your solution, it seems it solved my problem. I had
to write code for copying each element of my double[] into an ad-hoc
Double[], returning a Result created with a private constructor taking
the ad-hoc Double[] (i.e. I implemented the Factory Method Pattern,
http://en.wikipedia.org/wiki/Factory_method_pattern).

@ markspace: I meant I changed the type of the object that I actually
passed to the method: the signature of the method wants a Number[], if
I pass an int[] it doesn't like it, but if I pass an Integer[] it
does. Again, apologize me for the misunderstanding.

@chankey: the problem is a little more complex than a simple printing,
maybe you read only my first post. I sent another post in this thread
where I explained the question from a different point of view. Thank
you anyway.

Again, many thanks to you all! I hope I can return!


Simone.
 
M

markspace

@ markspace: I meant I changed the type of the object that I actually
passed to the method: the signature of the method wants a Number[], if


Ah ok. Well here is one pattern you can use:

private static String process( Object ii )
{
if( ii instanceof int[] ) {
return Arrays.toString( (int[]) ii );
} else if( ii instanceof double[] ) {
return Arrays.toString( (double[]) ii );
} else {
throw new IllegalArgumentException( "Sorry Charlie.");
}
}
 
S

Simone

@ markspace: I meant I changed the type of the object that I actually
passed to the method: the signature of the method wants a Number[], if

Ah ok.  Well here is one pattern you can use:

     private static String process( Object ii )
     {
         if( ii instanceof int[] ) {
             return Arrays.toString( (int[]) ii );
         } else if( ii instanceof double[] ) {
             return Arrays.toString( (double[]) ii );
         } else {
             throw new IllegalArgumentException( "Sorry Charlie.");
         }
     }

Yes, markspace! :)
I thought about a similar solution, but maybe the type in the
signature would have been a Number[], avoiding the risk that the
programmer could have passed an object of any type. I didn't like that
solution because I think the use of instanceof operator isn't
really really OOP. I wished a solution that was compile-time safe,
without the use of instanceof.
Anyway, a good alternative solution, thank you.

I hope a future release of Java will allow to autobox primitive-type
arrays and corresponding object arrays, just as it now allows autobox
for "single" primitive types into "single" objects.


Simone
 
M

markspace

I hope a future release of Java will allow to autobox primitive-type
arrays and corresponding object arrays, just as it now allows autobox
for "single" primitive types into "single" objects.


Yeah, Java definitely will not "autobox" arrays for you. The closest I
can get is to use strongly typed public methods and then one common
routine to give you a single point of maintenance (which will need to
use reflection).


public static String toStringA( int[] a ) {
return toStringI( a );
}
public static String toStringA( double[] a ) {
return toStringI( a );
}
private static String toStringI( Object array ) {
if( array.getClass().isArray() ){
StringBuilder sb = new StringBuilder();
sb.append( '(' );
if( Array.getLength( array ) > 0 ) {
sb.append( Array.get( array, 0) );
for( int i = 1; i < Array.getLength( array ); i++ ) {
sb.append( ',');
sb.append( Array.get( array, i ) );
}
}
sb.append( ')');
return sb.toString();
} else {
throw new IllegalArgumentException( "Sorry Charlie.");
}
}
 
C

ClassCastException

Hello,

I need to write a method for printing an array of numbers as a string
(e.g. "(2,5,7)" ). The numbers can be int or double and I wish to write
only one method for both types so, remembering that Java wraps primitive
types into their corresponding objects (int in Integer, double in
Double) I wrote a method:

public String print( Number[] data ){ ... }

When I try to invoke the print method with an int[] or a double[]
argument, I get an error:

"The method print(Number[]) in the type MyClass is not applicable for
the arguments (int[])"

Don't use arrays. Use collections such as List<Integer> and List<Double>.
Your primitives will be autoboxed in these and you can use:

public static String print (List<? extends Number> data) {
final StringBuilder sb = new StringBuilder();
sb.append("(");
boolean suppressComma = true;
for (Number n : data) {
if (suppressComma)
suppressComma = false;
else
sb.append(",");
sb.append(n.toString());
}
sb.append(")");
return sb.toString();
}

(untested)
 
A

Arne Vajhøj

@chankey: the problem is a little more complex than a simple printing,
maybe you read only my first post. I sent another post in this thread
where I explained the question from a different point of view.

It is usual beneficial to describe the real problem in
the first post.

Arne
 
A

Arne Vajhøj

Don't use arrays. Use collections such as List<Integer> and List<Double>.
Your primitives will be autoboxed in these and you can use:

That is good advice.

Collections should be default choice for developers
with arrays being chosen only for very specific reasons.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top