Java Forum / General / March 2007
Using Arrays and Collections
Philipp - 20 Mar 2007 19:22 GMT 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
Eric Sosman - 20 Mar 2007 19:51 GMT 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.)
 Signature Eric.Sosman@sun.com
Wojtek - 20 Mar 2007 20:00 GMT Eric Sosman wrote :
> Philipp wrote On 03/20/07 14:22,: >> Hello, [quoted text clipped - 15 lines] > 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.
 Signature Wojtek :-)
Michael Rauscher - 20 Mar 2007 20:09 GMT Eric Sosman schrieb:
> Philipp wrote On 03/20/07 14:22,: >> Hello, [quoted text clipped - 7 lines] > 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
Philipp - 20 Mar 2007 20:22 GMT > Eric Sosman schrieb: >> Philipp wrote On 03/20/07 14:22,: [quoted text clipped - 13 lines] > 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
Michael Rauscher - 20 Mar 2007 20:43 GMT > 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
Stefan Ram - 20 Mar 2007 21:00 GMT > 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; }}
Philipp - 21 Mar 2007 08:38 GMT >> for ( int i : intArray ) { >> if ( result == null ) [quoted text clipped - 21 lines] > if( array[ i ]> result )result = value; } > return result; }} Is there a good reason to do the for loop backwards?
Phil
Ingo R. Homann - 21 Mar 2007 10:24 GMT Hi,
>> for( int i = array.length - 1; --i >= 0; ) > > 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
Tom Hawtin - 21 Mar 2007 11:24 GMT > 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
Chris Uppal - 21 Mar 2007 21:33 GMT > > Is there a good reason to do the for loop backwards? > [quoted text clipped - 6 lines] > 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
Stefan Ram - 21 Mar 2007 14:14 GMT >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.
Lew - 21 Mar 2007 19:55 GMT > public static int max > ( final int[] a ) [quoted text clipped - 7 lines] > 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
Chris Uppal - 21 Mar 2007 21:39 GMT > 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
Stefan Ram - 21 Mar 2007 23:13 GMT >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.
Wojtek - 21 Mar 2007 23:24 GMT Stefan Ram wrote :
> If I am writing code as an employee, I surely will have to > follow the employers coding conventions. In the Usenet, I am [quoted text clipped - 6 lines] > enable this, to please people. But not having this, I do > not want to do extra effort. I do go through the trouble of formating the code I present to Usenet, and it has nothing to do with the Sun style.
I just try to make it as readable as possible, following the thinking that if it is easy to read, then people will be more likely to respond.
And easy to read in my lexicon is indented, white space between language elements, braces on ther own line, statements on their own line, and paragraphing code where applicable.
But I applaud your wanting to do it your way, even though I did not actually read through the code you presented....
 Signature Wojtek :-)
Chris Uppal - 22 Mar 2007 13:34 GMT > Sometimes, it is difficult to tell whether you are doing the > right thing in spite of a crowd of mislead people trying to [quoted text clipped - 3 lines] > rule (such as »Always ignore criticism.« or »Always do as the > crowd.«) is always right. I think there's more practical value in considering whether it is expedient to act /as if/ the crowd is correct, without regard to the underlying truth (if any).
"Expedient" carries a slightly negative connotation, more so than I really mean, but I can't think of a more neutral word off-hand.
Personally, and on such topics, I consider it a valuable contribution all by itself to remind the majority that they are /only/ the majority -- an accident of numbers, not a matter Universal Law or Platonic Truth -- and perhaps not so great a majority as some of its members might imagine.
-- chris
Lew - 23 Mar 2007 13:28 GMT >> Sometimes, it is difficult to tell whether you are doing the >> right thing in spite of a crowd of mislead people trying to [quoted text clipped - 15 lines] > of numbers, not a matter Universal Law or Platonic Truth -- and perhaps not so > great a majority as some of its members might imagine. Fine, if you don't want your code to be easy to read for the people from whom you are soliciting assistance. I fully support anyone's right to defy the crowd, even if it means being lonely.
-- Lew
Daniel Pitts - 21 Mar 2007 00:59 GMT > > Is there a nice way to find the maximum number in an int array then? > [quoted text clipped - 16 lines] > 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[i] > max) { max = array[i]; } } return new Integer(max); }
Michael Rauscher - 21 Mar 2007 08:16 GMT 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
Danno - 20 Mar 2007 21:02 GMT > > Eric Sosman schrieb: > >> Philipp wrote On 03/20/07 14:22,: [quoted text clipped - 17 lines] > > Thanks Phil List<Integer> myList2 = Arrays.<Integer>asList(1,4,3); int max = Collections.<Integer>max(myList2);
Danno - 20 Mar 2007 21:05 GMT > > > Eric Sosman schrieb: > > >> Philipp wrote On 03/20/07 14:22,: [quoted text clipped - 20 lines] > 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);
Michael Rauscher - 21 Mar 2007 08:35 GMT > 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[i] = intArray[i]; 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
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|