Using Arrays and Collections

P

Philipp

Hello,

What's wrong with this code?

int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));


(Java 1.5)
Thanks for any help
Phil
 
E

Eric Sosman

Philipp wrote On 03/20/07 14:22,:
Hello,

What's wrong with this code?

int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));

Arrays.asList() requires an array of object references
and returns a List of object references. An int value is
not an object reference.

(Rant: This is why autoboxing is evil. It encourages
people to forget the distinction between primitives and
references, thus promoting mistakes like the above. Some
have argued that the evil lies not in the autoboxing but
in the very existence of primitives, but that doesn't let
autoboxing off the hook: If primitives behaved like objects,
autoboxing would be a no-op.)
 
W

Wojtek

Eric Sosman wrote :
Philipp wrote On 03/20/07 14:22,:
Hello,

What's wrong with this code?

int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));

Arrays.asList() requires an array of object references
and returns a List of object references. An int value is
not an object reference.

(Rant: This is why autoboxing is evil. It encourages
people to forget the distinction between primitives and
references, thus promoting mistakes like the above. Some
have argued that the evil lies not in the autoboxing but
in the very existence of primitives, but that doesn't let
autoboxing off the hook: If primitives behaved like objects,
autoboxing would be a no-op.)

Which is why I have Ecplise treat autoBoxing / autoUnBoxing as an
error.
 
M

Michael Rauscher

Eric said:
Philipp wrote On 03/20/07 14:22,:
Hello,

What's wrong with this code?

int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));

Arrays.asList() requires an array of object references
and returns a List of object references. An int value is
not an object reference.

Arrays.asList uses a variable length argument list, so it doesn't
require an array. It returns a List<int[]> and since arrays don't
implement the Comparable interface, Collections.max can't be used on
such lists.

Bye
Michal
 
P

Philipp

Michael said:
Eric said:
Philipp wrote On 03/20/07 14:22,:
Hello,

What's wrong with this code?

int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));

Arrays.asList() requires an array of object references
and returns a List of object references. An int value is
not an object reference.

Arrays.asList uses a variable length argument list, so it doesn't
require an array. It returns a List<int[]> and since arrays don't
implement the Comparable interface, Collections.max can't be used on
such lists.

Is there a nice way to find the maximum number in an int array then?

Thanks Phil
 
M

Michael Rauscher

Philipp said:
Is there a nice way to find the maximum number in an int array then?

Try

Integer max( int[] intArray ) {
Integer result = null;
for ( int i : intArray ) {
if ( result == null )
result = Integer.valueOf(i);
else if ( i > result.intValue() )
result = Integer.valueOf(i);
}
return result;
}

This method returns null if the intArray is of length 0.

Bye
Michael
 
S

Stefan Ram

Michael Rauscher said:
for ( int i : intArray ) {
if ( result == null )
result = Integer.valueOf(i);
This method returns null if the intArray is of length 0.

Sun should have provided such a method.

Probably, there is one in the Apache Commons, but I did
not care to search for it.

My own code tries to avoid the »if( result == null )«
within the loop, doing an »result = array[ array.length - 1 ];«
once outside the loop. I have not tested it.

public class IntArrayUtils
{ public static int max
( final int[] array )
{ int result = 0;
if( array.length == 0 )
throw new java.lang.IllegalArgumentException( "array.length == 0" );
else
{ result = array[ array.length - 1 ];
for( int i = array.length - 1; --i >= 0; )
if( array[ i ]> result )result = value; }
return result; }}
 
D

Danno

Michael said:
Eric said:
Philipp wrote On 03/20/07 14:22,:
Hello,
What's wrong with this code?
int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));
Arrays.asList() requires an array of object references
and returns a List of object references. An int value is
not an object reference.
Arrays.asList uses a variable length argument list, so it doesn't
require an array. It returns a List<int[]> and since arrays don't
implement the Comparable interface, Collections.max can't be used on
such lists.

Is there a nice way to find the maximum number in an int array then?

Thanks Phil


List<Integer> myList2 = Arrays.<Integer>asList(1,4,3);
int max = Collections.<Integer>max(myList2);
 
D

Danno

Michael said:
Eric Sosman schrieb:
Philipp wrote On 03/20/07 14:22,:
Hello,
What's wrong with this code?
int[] intArray = {1,4,3};
int max = Collections.max(Arrays.asList(intArray));
Arrays.asList() requires an array of object references
and returns a List of object references. An int value is
not an object reference.
Arrays.asList uses a variable length argument list, so it doesn't
require an array. It returns a List<int[]> and since arrays don't
implement the Comparable interface, Collections.max can't be used on
such lists.
Is there a nice way to find the maximum number in an int array then?
Thanks Phil

List<Integer> myList2 = Arrays.<Integer>asList(1,4,3);
int max = Collections.<Integer>max(myList2);

BTW..If you want to keep the array, you just need box it to an
Integer...

Integer[] intArray = {1,4,3};
List<Integer> myList2 = Arrays.<Integer>asList(intArray);
int max = Collections.<Integer>max(myList2);
System.out.println(max);
 
D

Daniel Pitts

Philipp said:
Is there a nice way to find the maximum number in an int array then?

Try

Integer max( int[] intArray ) {
Integer result = null;
for ( int i : intArray ) {
if ( result == null )
result = Integer.valueOf(i);
else if ( i > result.intValue() )
result = Integer.valueOf(i);
}
return result;

}

This method returns null if the intArray is of length 0.

Bye
Michael

Cleaner and more optimized version, suitable for earlier versions of
java:

Integer max(int[] array) {
if (array == null || array.length == 0) {
return null;
}
int max = array[0];
for (int i = 1; i < array.length; ++i) {
if (array > max) {
max = array;
}
}
return new Integer(max);
}
 
M

Michael Rauscher

Hello again,

of course, Stefan and Daniel are right. One shouldn't test the condition
in every iteration of the loop. Moreover if the test is done in advance,
one can eliminate the need to use Integer inside the loop.

A last thing: Since I don't consider a zero length array to be an
exceptional case, I prefer Daniel's version.

Bye
Michael
 
M

Michael Rauscher

Danno said:
List<Integer> myList2 = Arrays.<Integer>asList(1,4,3);
int max = Collections.<Integer>max(myList2);

Even shorter: int max = 4;

Just joking, but it points out that I consider that neither the elements
nor the number of elements are known in advance.

How to implement a method max(int[] intArray)?

You could assume an array of Integer, of course. But in this case you'd
answer a question that didn't arise.

One could implement the method using a local array of Integer.

Integer tempArray[] = new Integer[intArray.length];
for ( int i=0; i < intArray.length; i++ )
tempArray = intArray;
int max = Collections.max(Arrays.asList(tempArray));

This would be at least as stupid than my version that has some drawbacks
as Stefan and Daniel already mentioned. I'd suggest to use Daniel' version.

Bye
Michael
 
P

Philipp

Stefan said:
Michael Rauscher said:
for ( int i : intArray ) {
if ( result == null )
result = Integer.valueOf(i);
This method returns null if the intArray is of length 0.

Sun should have provided such a method.

Probably, there is one in the Apache Commons, but I did
not care to search for it.

My own code tries to avoid the »if( result == null )«
within the loop, doing an »result = array[ array.length - 1 ];«
once outside the loop. I have not tested it.

public class IntArrayUtils
{ public static int max
( final int[] array )
{ int result = 0;
if( array.length == 0 )
throw new java.lang.IllegalArgumentException( "array.length == 0" );
else
{ result = array[ array.length - 1 ];
for( int i = array.length - 1; --i >= 0; )
if( array[ i ]> result )result = value; }
return result; }}

Is there a good reason to do the for loop backwards?

Phil
 
I

Ingo R. Homann

Hi,
Is there a good reason to do the for loop backwards?

There is a reason, but it is a very bad one. ;-/

The reason normally mentioned ist that on most processors the comparison
'>=0' is very fast whereas the comparison '<array.length' is slower,
so that the loop should be faster.

It is true that the comparison is faster but unfortunately it does not
take into account, that many (meanwhile all?) processors do have a cache
for the array-elements and that this cache is *highly* *optimized* for
increasing access. Decreasing access will slow them down.

So, in practise, the dercreasing loop is indeed often *slower*!

The decreasing loop is normally a (bad) approach of a former assembler
programmer to "optimize" his java code.

Ciao,
Ingo
 
T

Tom Hawtin

Ingo said:
It is true that the comparison is faster but unfortunately it does not
take into account, that many (meanwhile all?) processors do have a cache
for the array-elements and that this cache is *highly* *optimized* for
increasing access. Decreasing access will slow them down.

And Sun's HotSpot optimises forward loops better than backward loops (as
backward loops are rare and so not worth complicating already
complicated code).
So, in practise, the dercreasing loop is indeed often *slower*!

Indeed.

Tom Hawtin
 
S

Stefan Ram

Philipp said:
Is there a good reason to do the for loop backwards?

In the meantime, this has been answered by others.

So, here is my next attempt:

public static int max
( final int[] a )
{ int result = 0;
if( a.length == 0 )
throw new java.util.NoSuchElementException
( "The argument value was an empty array, " +
"but I can't compute the maximum of an empty array." );
else
{ result = a[ 0 ];
for( int i : a )if( i > result )result = i; }
return result; }

The exception-behavior is now the same as that of

http://download.java.net/jdk7/docs/api/java/util/Collections.html#max(java.util.Collection)

, which also throws

http://download.java.net/jdk7/docs/api/java/util/NoSuchElementException.html

if there is no element.

The loop now iterates over all components of the array, but
the body stil only does one test per iteration.

By this, finding the optimum implementation of loop details
now was left to the compiler.
 
L

Lew

Stefan said:
public static int max
( final int[] a )
{ int result = 0;
if( a.length == 0 )
throw new java.util.NoSuchElementException
( "The argument value was an empty array, " +
"but I can't compute the maximum of an empty array." );
else
{ result = a[ 0 ];
for( int i : a )if( i > result )result = i; }
return result; }

Your code would be easier to read if you followed standard Java source code
formatting conventions for your Usenet posts.

-- Lew
 
C

Chris Uppal

Ingo said:
Is there a good reason to do the for loop backwards?

There is a reason, but it is a very bad one. ;-/

The reason normally mentioned ist that on most processors the comparison
'>=0' is very fast whereas the comparison '<array.length' is slower,
so that the loop should be faster.

It is true that the comparison is faster but unfortunately it does not
take into account, [...]

Another thing it fails to take into account is the fact that desktop (or
better) class processors do speculative execution, so while the test
implementing the range check is running, the code implementing the next
iteration of the loop is usually /already/ executing.

-- chris
 
C

Chris Uppal

Lew said:
Stefan Ram wrote: [...]
Your code would be easier to read if you followed standard Java source
code formatting conventions for your Usenet posts.

But Stefan's already explained his reasons (twice, at least -- I know 'cos I
asked once too). And he's made a reasoned decision. If his position is that
it's the /rest/ of us who are wrong, then -- quite legitimately -- he's not
likely to change.

It's dead certain that I'll never use the vile Sun-style layout in Usenet
posts. My reasons are -- in my considered opinion -- more than sufficient.
Why should Stefan see the matter any differently ?

-- chris
 
S

Stefan Ram

Chris Uppal said:
It's dead certain that I'll never use the vile Sun-style layout
in Usenet posts. My reasons are -- in my considered opinion --
more than sufficient. Why should Stefan see the matter any
differently ?

Sometimes, it is difficult to tell whether you are doing the
right thing in spite of a crowd of mislead people trying to
lead you astray or whether you are doing the wrong thing in
spite of a crowd of fine people trying to show you the way: In
both cases you find yourself on the other side, and no general
rule (such as »Always ignore criticism.« or »Always do as the
crowd.«) is always right.

If I am writing code as an employee, I surely will have to
follow the employers coding conventions. In the Usenet, I am
writing in my leisure and solely for my personal fun. So, in
this case, I feel free to format the source code as I please.

However, I do not whish to offend anyone. If my newsreader
would be able to automatically reformated included source
code to Sun's Convention when sending a posting, I would
enable this, to please people. But not having this, I do
not want to do extra effort.

Here are quotations of people with some trust in »their way«:

»And do it your way...it's the only way.«
Emerson, Lake and Palmer, Tarkus

»There are so many people, and I can't please
them all, so I better might please nobody«
Bob Dylan (from my memory, can't find the source)

»If I had a motto, it would probably be herd thither, me hither.«
Erik Naggum
http://ungregarious.org/2004/

»I think the most important characteristic of an
entrepeneur is that they're going to do it whether you
give them permission or not.«
Eric Schmidt
http://blog.outer-court.com/archive/2007-03-20-n29.html

But then, the last attribute might also apply to a criminal.
 

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

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top