• 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
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Exception with Map.getOrDefault

 
Bartender
Posts: 5546
213
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have this code:

where the variable 'test' indicates whether a program counter must be adjusted by the last number. The command 's' can also come in this form: 'jnz 5 3'.

The last line gives me the exception:  Exception in thread "main" java.lang.NumberFormatException: For input string: "c".

Maybe I am getting too old for this, but what am I doing wrong?
 
Saloon Keeper
Posts: 28313
207
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Looks to me like you're trying to parse the string whose value is "c" as an integer. Definitely a NumberFormat problem, that.

You didn't forget that arrays start at 0, did you? When you split the string "jnz c 2"?
 
Sheriff
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't you mean Integer.parseInt(array[2]) instead of Integer.parseInt(array[1])?
 
Piet Souris
Bartender
Posts: 5546
213
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is day 12 of Advent Of Code 2016. This is the instruction:

Here x is either the variable a, b, c or d, or an int like 5.
As you see, I put the variables in a hashmap<String, Integer>, and the idea was that if array[1] (that is either that variable or an integer) is a key in the map, then take its value, or else array[1] is an integer that I will then parse.

It seems that java calculates the default value even if the key is present. But maybe there is some other explanation.
 
Tim Holloway
Saloon Keeper
Posts: 28313
207
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, the compiler is compiling argument expressions for a method invocation. It has no way of knowing whether those arguments will be used or not.
 
Sheriff
Posts: 28321
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You'd need a Supplier<Integer> to implement the idea that you'd only compute the value on demand, but Map.getOrDefault doesn't have a method Map.getOrDefault(Object, Supplier<V>).
 
Master Rancher
Posts: 5057
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yeah.  You could achieve this with computeIfAbsent(), but it would have the side effect of storing the newly computed value in the map.  Which might be fine, but seems unnecessary for this use case.

I think it's best to just code what you want directly yourself:
 
Tim Holloway
Saloon Keeper
Posts: 28313
207
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Something more like

I think that the only the predicate that matches the test result gets computed.
 
Mike Simmons
Master Rancher
Posts: 5057
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, that would work too.  (Yes, parseInt() is not called unless the contains() is false.)  I reflexively avoid the contains() method because it seems wasteful to do that and then a get() - I prefer to just do the get and test for null. But then I need another temp variable to hold it in, so I extracted a method, thinking Piet may use it again for other arguments in the code.  But, six of one, half dozen of the other - either way works.
 
Tim Holloway
Saloon Keeper
Posts: 28313
207
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Yes, that would work too.  (Yes, parseInt() is not called unless the contains() is false.)  I reflexively avoid the contains() method because it seems wasteful to do that and then a get() - I prefer to just do the get and test for null. But then I need another temp variable to hold it in, so I extracted a method, thinking Piet may use it again for other arguments in the code.  But, six of one, half dozen of the other - either way works.



Æsthetically, I'd pre-calculate the key into a temporary variable, but that's largely for maintainability.  The compiler can optimize out any of the above.

To avoid contains/get, something like this:

Not as elegant, but it avoid the extra lookup.

On the other hand, the trinary operation works when you want test to be final.
 
Rob Spoor
Sheriff
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It can be made more elegant by using Optional:
 
Piet Souris
Bartender
Posts: 5546
213
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I used what Tim suggested:

but Rob, that is indeed very nice! Deserves a cow!

I translated the input into an ArrayList<Runnable>, so in this case I had:


Edit:

@Rob,
any reason why you used orElseGet instead of orElse?
 
Rob Spoor
Sheriff
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:@Rob,
any reason why you used orElseGet instead of orElse?


The argument to orElse isn't lazily evaluated, so you'd have the same problem you originally had - array[1] is parsed even if it isn't necessary, and it fails for any non-number.
 
Nothing up my sleeve ... and ... presto! A tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic