Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

What's happening: integer array?  RSS feed

 
Ben Poland
Ranch Hand
Posts: 97
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey guys,

Totally new to this site and just started playing with Java yesterday! So er, yeah, total nooby here

I am trying to understand how this is working? It is an exercise from another website.

int[] aryNums = {24, 6, 47, 35, 2, 14 };

Arrays.sort(aryNums);
int lastArrayNumber = aryNums.length - 1;
System.out.println("Highest Number: " + aryNums[lastArrayNumber]);

The task is to print out the highest value in the array, but I don't really understand what's happening to make that happen. Here's what I see happening:
So, the array "aryNums" is created and a value is added to each cell within that array in the order stated between { }. Arrays.sort will then sort in ascending order the values of the cells. This is where I don't get what's happening... The following line "int lastArrayNumber = aryNums.length - 1;". What is being specified in that line that will display the highest number? And how is it doing that?

Very noob I know, but hey, we all have to start somewhere

Thanks in advance for any help with this.
 
Svetlana Rosemond
Greenhorn
Posts: 17
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When you declare an array you either have to specify the length like this



or



Now, think about it this way. If I asked you to count to 3, how would you do it? Most people will say 1,2,3. However, computers don't work that way, they start at 0. So when you declare an array of 3 elements, it's really 0,1,2, which are the indexes in your array.



The above line of code, doesn't determine the highest amount, the Array.Sort did. All your doing with the above line is access the number specified at the index which is determined when you subtract the length minus 1. Remember, the computer doesn't see 1-6 as humans do, it sees 0 - 5, however, because the length of the array is 6, you have to minus 1 to access the last element(which is stored at the index of 5).

 
Ben Poland
Ranch Hand
Posts: 97
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey there,

Thanks for the reply.

Ok, I understand what you mean, I think... ? So what part of that code is actually telling "Array.sort" to find and print the highest value in the array? lol Sorry

Ben

 
Svetlana Rosemond
Greenhorn
Posts: 17
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ben Poland wrote:Hey there,

Thanks for the reply.

Ok, I understand what you mean, I think... ? So what part of that code is actually telling "Array.sort" to find and print the highest value in the array? lol Sorry

Ben



Array.Sort() doesn't print it, but it did determine the highest number. To understand how it did that, you would have to do some reading about comparing object which might be too much for you at this point. If you want, you could read the official documentation that explains Array.Sort. System.out.Println() printed it.

 
Ben Poland
Ranch Hand
Posts: 97
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oops, my bad... Yes, I know which part of code is actually responsible for displaying the output on screen, I just meant what part of the code is actually telling Arrays.sort to find the highest number in the array? And how is it doing that? I have to get used to terms used

Thanks again though and sorry if I get annoying

Ben
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Arrays#sort comes in several different versions, but I think that link is the version you are using. It does not look for the largest element, but sorts the array in ascending order. So to find the largest element, you call myArray[myArray.length − 1] as SR has already told you The syntax with myArray.length − 1 looks clumsy, but you should always use it because it is more reliable than writing a number.
That is not a very good way to find the largest element in the array for at least two reasons:-
  • 1: It takes longer to sort than a simple search would have.
  • 2: It alters the state of the array, and actually destroys information about its original state (order of elements).
  • 3: I have thought of a 3rd reason: Ben Poland can't understand it.
  • Yes, the fact that you have code which you can't understand makes it bad code.

    I would find the maximum like this:-What you are doing there is creating an object from this; the of() method can take an array and turn it into an IntStream. That stream object will run through all the values and the max() method does what it says on the tin: it finds the largest value. But if you run that code, you will find it doesn't simply return an int. It returns something different just in case it is passed an empty array and there isn't a maximum at all. You should be able to tell from the output what the max value was, or you can get an int by changing the last line of my code to:-If there was no maximum it will print −2147483648.

    If you know how to write a loop, you could consider working out how to find the largest value in your array without sorting anything. That would be how we used to do things before Streams were introduced in Java8. Note the strange indentation with all the dots aligned vertically.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Wow, thanks for the reply, Campbell. I tried using the code you suggested, much easier to understand and follow and like you said, does exactly what it says on the tin

    So, just to make sure I understand this:

    int[] aryNums = {24, 6, 47, 35, 2, 14 }; //Creates the array and assigns the values to each index in that array as specified in the { }

    System.out.println("Highest Number: " + IntStream.of(aryNums) //Prints to screen "Highest number: " while IntStream then searches through the array
    .max()); //Finds the highest value in the array which is then printed to screen using the System.out.printIn from the above line

    I hope that I'm understanding that correctly?

    Ben

     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Oh... The output after running that code is:

    Highest Number is: OptionalInt[47]

    I assume the OptionalInt is printed out, like you said in case the array doesn't actually have any maximum value?

    Ben
     
    Campbell Ritchie
    Marshal
    Posts: 55715
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Try it with
    int[] myArray = {};
    ... and see what the optional displays.

    I would say there is a simpler way to understand the array initialsier:-
    Create an array containing 24, 6, 47, 35, 2, and 14.
    Beware: the full syntax for an array initialiser is this:-
    int[] myArray = new int[]{24, 6, 47, 35, 2, 14};
    If yo uhave the declaration and initialisation on the same line, you are allowed to omit the new int[] part.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ok, tried it 2 other ways:

    int[] aryNums = {};

    System.out.println("Highest Number is: " + IntStream.of(aryNums)
    .max());
    //.orElse(Integer.MIN_VALUE));

    Output:
    Highest Number is: OptionalInt.empty

    int[] aryNums = {};

    System.out.println("Highest Number is: " + IntStream.of(aryNums)
    .max()
    .orElse(Integer.MIN_VALUE));

    Output:
    Highest Number is: -2147483648

    Output 1 simply because there are no values in the array?
    Output 2 because the Integer.MIN_VALUE is -2147483648? So that then becomes the maximum number as there are no other values.

    I assume that's the case.

    With regard declaration and initialisation being on the same line, allowing new int[] to be omitted, is there a best practice for that? I mean is best practice to remove it?

    Thanks again guys, really appreciate that help from both of you.

    Ben
     
    Campbell Ritchie
    Marshal
    Posts: 55715
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ben Poland wrote: . . .Output 1 simply because there are no values in the array?
    Yes. That is the default behaviour for a String with no elements.
    Output 2 because the Integer.MIN_VALUE is -2147483648? So that then becomes the maximum number as there are no other values. . . .
    No. That is because I called the orElse() method and told it to use that minimum value if there is no value already supplied. Look at the link, which I hope will make things clear.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hey Campbell,

    All makes sense now. Thank you for your help with this, very much appreciated...

    Have a great day

    Ben

     
    Campbell Ritchie
    Marshal
    Posts: 55715
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    My pleasure.

    And now we have a Rancher who can write simple Streams and can't yet write loops, have we? In the immortal words of Homer Simpson,
    Woohoo!
    I hereby challenge you to find the maximum value in that array the way we had to do it with Java7 before the streams API was introduced.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Challenge accepted

    Ben
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hey again, Campbell,

    So I decided to add to the challenge a little by also finding the lowest number in the array

    How does this look to you?



    Does exactly what I intended it to do, but is there a better, more straightforward approach to it perhaps?

    Thanks again, Sheriff

    Ben
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    And er, keep those challenges coming please, enjoyed that ;)

    Thanks again,

    Ben
     
    Campbell Ritchie
    Marshal
    Posts: 55715
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    That is exactly how I would have done it when I started with Java1.4 The one enhancement I would suggest is that you can use a for‑each loop (officially called enhanced forBeware: link can be difficult to read) now that Java1.4 is history.
    As an alternative, you can start with highValue = Integer.MIN_VALUE; and lowValue = Integer.MAX_VALUE; Those will give some sort of result if you pass an empty array to such a method. Find out what happens if you pass an empty array to lines 3‑4.

    The code with a Stream is neater, isn't it? Another challenge: how to get both maximum and minimum out of the same IntStream.

    I shall be away for a week or so; somebody else will have to give you the next challenge.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I actually just prefer using Integer.MAX_VALUE / MIN_VALUE, seems cleaner, safer and just to the naked eye makes more sense, so will make a point of using this in the future.

    So, output when passing an empty array:

    The highest value in this array is: -2147483648
    The lowest value in this array is: 2147483647

    That's what I would expect after your example yesterday.



    Output is:

    The highest value in this array is: OptionalInt[47]
    The lowest value in this array is: OptionalInt[2]

    So the result is as it should be. So much neater, yes. Just to look at it makes far more sense. One question regarding this though, yesterday I was able to add the .orElse(Integer.MIN_VALUE); to remove that OptionalInt prior to the value, how do I do that now? :/

    Ben
     
    Paul Clapham
    Sheriff
    Posts: 22487
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Well, I'm way behind in learning the new Streams features in Java 8 but my guess would be that you just add the call to .orElse() in exactly the same way. That's just a guess but I think it has a good chance of being right, and if it isn't the error message you get might point to the real right way.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hey Paul,

    I tried that, but it's giving me the error "illegal start of expression". I'm definitely missing something simple here... I'm poking about with it, trial and error will get me an answer

    Ben
     
    Paul Clapham
    Sheriff
    Posts: 22487
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Does your expression now look like this?

     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hey again, Paul

    No, I currently have it printing both the highest and lowest values in the array as follows:



    So I'm kind of stuck as to what to specify in order to remove the OptionalInt in the print as both IntStream.of(aryVals) min and max are being used. I think or.Else isn't applicable here as it's giving the 2 results requested and there isn't an .orElse anything... I hope I'm making some kind of sense?

    Ben
     
    Paul Clapham
    Sheriff
    Posts: 22487
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Paul Clapham wrote:Does your expression now look like this?



    I asked that because right now you have this:



    and the obvious place to insert the call to .orElse() is at the end.

    Probably it doesn't help that your IDE has split up that expression to make the code look neater (or something) because it makes it harder for the beginner to see.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    So here's how it looked when I was just wanting to get the highest value from the array:



    In order to get both the highest and lowest values from the array I had to add the following:



    So now it does indeed print off both the highest and lowest values, but the output is displayed as:

    The highest value in this array is: OptionalInt[47]
    The lowest value in this array is: OptionalInt[2]

    So it is doing exactly what I wanted it to do by displaying the values, but also showing OptionalInt prior to the value. It's just the OptionalInt part that I would like to not be displayed in the print. If I'm understanding this correctly, the .orElse applies if there is a possible other value which in this case there obviously isn't.

    Ben
     
    Paul Clapham
    Sheriff
    Posts: 22487
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ben Poland wrote:If I'm understanding this correctly, the .orElse applies if there is a possible other value which in this case there obviously isn't.


    No, you aren't understanding it correctly. The compiler doesn't look at the actual input array and figure out whether it might be empty (which to your eyes, it obviously isn't). The purpose of the orElse() method is to take an Optional<Integer> object and turn it into either the integer contained in the Optional<Integer> object, or else the number you give to the orElse() method. If you don't use the orElse() method then it doesn't turn the Optional<Integer> object into the integer which it contains.

    But you want it to turn that Optional<Integer> object into the integer. So my suggestion... well, I've posted it twice. I'm surprised you didn't just try it to see what happened.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Oops, sorry Paul, my bad I wasn't understanding what you meant so was just adding the .orElse at the end on it's own and not at the end of each line. Just got what you mean, tried it and it works fine



    That's how it is now and it's all good.

    Thanks for the help.

    Ben

    P.S. Fancy throwing a challenge at me? Seems a good way to learn things...
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ben Poland wrote:Oops, sorry Paul, my bad I wasn't understanding what you meant so was just adding the .orElse at the end on it's own and not at the end of each line. Just got what you mean, tried it and it works fine Also I understand properly what the .orElse method is doing now.



    That's how it is now and it's all good.

    Thanks for the help.

    Ben

    P.S. Fancy throwing a challenge at me? Seems a good way to learn things...
     
    Campbell Ritchie
    Marshal
    Posts: 55715
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Bad news: I am back

    No, I wouldn't do it like that myself. You are creating two separate Streams. You can do it with one Stream and call a method to get a summary. Look at that link and the included links and I think you will find a simpler solution.
     
    Ben Poland
    Ranch Hand
    Posts: 97
    2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    lol Not bad news, wb Campbell Hope you had a good time!

    Righty, looking into this one quickly...

    Let the challenges continue ;)

    Ben
     
    With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!