Increment array value using array[key]++ - java

My Java code:
if(wins.containsKey(winner)) {
int currentCount = wins.get(winner);
wins.remove(winner);
wins.put(winner, currentCount + 1);
} else {
wins.put(winner, 1);
}
This was my alternative to something I can do in PHP and even C#:
if(isset($something[$key])) {
$something[$key]++;
} else {
$something[$key] = 1;
}
This is going to be used in a high number of iterations in a for loop so I would like to consider performance. Is this whole remove() then puts() business killing the performance? What is an alternative?

Your code can be replaced to:
if(wins.containsKey(winner)) {
wins.put(winner, wins.get(winner) + 1);
} else {
wins.put(winner, 1);
}
No need to remove the entry. When you add another entry in the map with same key, it will overwrite the existing one.

The way I usually do this to be as efficient as possible is:
Integer val = wins.get(winner);
wins.put(winner,val == null ? 1 : (val + 1));
This is very clean to me and avoids the extra hash lookup to "get" the val after you know it's already in there from the contains.

Firstly, I strongly suspect that this isn't going to be a performance bottleneck. As ever, test the simplest code that works before you use more complicated code.
You could use AtomicInteger instead of Integer as the value type of your map. That would allow you to mutate the wrapped value, rather than replacing the whole entry. Then you'd have:
if(wins.containsKey(winner)) {
wins.get(winner).incrementAndGet();
} else {
wins.put(winner, new AtomicInteger(1));
}
If you can stick with Integer, you could still optimize your code further:
Integer previousValue = wins.get(winner);
int newValue = previousValue == null ? 1 : (int) previousValue + 1;
wins.put(winner, newValue);
Now there is exactly one get and one put operation on each iteration.

Related

How to increment a "number" in a Java 8 lambda expression in a loop?

I have the following problem. I have an integer position which starts at 1 and increments every time a specific person from a txt is found at a specific position in an xml. If I use the classic iteration with the foreach for (PersonMatchInfo pmi : personMatchInfo) it works, but my senior asked me to do with the Java 8 foreach and this type of iteration works only with final variables. How can I increment the integer in the new Java 8 loop? Thank you.
int position = 1;
personMatchInfo.forEach(pmi ->{
if (!stopwatch1.isStarted()) {
stopwatch1.start();
} else if (stopwatch1.isStarted()) {
}
if (pmi.getPersonName().equals(e.getValue())) {
positionMap.put(position, positionMap.get(position) + 1);
break;
} else {
position++;
}
});
You can use AtomicInteger, and incrementAndGet method on it.
Other solution would be int[] position = new int[]{1};
and incrementing position[0]++;
You can use a static variable :
public class Poubelle {
private static int position = 1;
public static void setPosition (List<PersonMatchInfo> listPersonMatchInfo) {
listPersonMatchInfo.forEach(pmi -> {
pmi.setPosition(position++);
});
}
}
I think you senior is asking you to use streams for collections.
Then use collection.stream.filter.count based on your logic that will produce a long as the value and use it.
I know it is late, so I will just put it out here for future seekers.
Here is how you can do it in a very simple way :
use indexOf(Object O) property of collections
StringBuffer messageBody = new StringBuffer();
List<VipObj> listOfAllVips = getResponse();
listOfAllVipsLocal.forEach(vip -> {
messageBody.append("\n\t" + (listOfAllVipsLocal.indexOf(vip) + 1) + ". " + vip.getBaseUrl() + "\n");
});

Nicely written check for numbers that can be null in java

I have an application where I need to handle a lot of numbers (Integers or Longs) comming from external sources.
The numbers can be null. In case they are null I always need to convert them to 0.
The problem seems trivial, but I don't want to write hundreds of times:
if (someNumber == null) {
someNumber = 0;
}
I don't like it for two reasons:
I don't like to write three lines of code for such simple task, especially because I need to do it many times
I don't like to to "mutate" someNumber (assign new value to someNumber variable)
I tried some other ways which can be seen here:
public static void main(String[] args) {
Integer zeroOrNull = new Random().nextBoolean() ? 0 : null;
// version1: this is nasty (I already mentioned why)
if (zeroOrNull == null) {
zeroOrNull = 0;
}
// version2: this seems to much for so simple task...
zeroOrNull = Optional.ofNullable(zeroOrNull).orElseGet(() -> 0);
// version3: creating an util might be considerable. Is there already such predefined util ?
zeroOrNull = MyUtil.getValueOrZero(zeroOrNull); // returns value or )
System.out.println(zeroOrNull); // I want 0 here in case of null
}
What is the preffered and nice way to do such "test for null/conversion to 0" ? Any chance to do this conversion implicitly?
Use i = (i==null)?0:i;
one line check
no method call
plain and simple
no additional dependency (unlike some other proposed solutions)
Place this check as close to your numbers source as possible, to avoid unnecessary duplications.
By creating overloaded versions of Null Checker
public static void main(String args[]) {
Integer intObj = null;
System.out.println("intObj : " + checkNull(intObj));
intObj = 1122222;
System.out.println("intObj : " + checkNull(intObj));
Long longObj = null;
System.out.println("longObj : " + checkNull(longObj));
longObj = 666555556L;
System.out.println("longObj : " + checkNull(longObj));
System.out.println("*********With default value***********");
intObj = null;
System.out.println("intObj : " + checkNull(intObj, 1));
intObj = 1122222;
System.out.println("intObj : " + checkNull(intObj, 1));
longObj = null;
System.out.println("longObj : " + checkNull(longObj, 0L));
longObj = 666555556L;
System.out.println("longObj : " + checkNull(longObj, 0L));
}
static Integer checkNull(Integer obj) {
if (obj == null)
return 0;
return obj;
}
static Long checkNull(Long obj) {
if (obj == null)
return 0L;
return obj;
}
static Integer checkNull(Integer obj, int i) {
if (obj == null)
return i;
return obj;
}
static Long checkNull(Long obj, long l) {
if (obj == null)
return l;
return obj;
}
A simple solution would be to write a utility method like below:
public static Integer checkNullNumber(Integer i){
if(i == null)
return 0;
return i;
}
Now you can use this method wherever you want like:
zeroOrNull = checkNullNumber(zeroOrNull);
I don't like to write three lines of code for such simple task,
especially because I need to do it many times
if (zeroOrNull == null) zeroOrNull = 0;
I don't like to to "mutate" someNumber (assign new value to someNumber
variable)
there is no way to change the null-value into a "0" without constructing a new Integer object that holds this "0" and this single line of code does just that
Use java8 java.util.Optional class is very efficient, but don't use
explicit null values, use empty Optional
This is my original answer, if "efficient" was intended only by "performance" I've wronged word, sorry.
The mean is that all coding process is better, develop and execution are more safe.
http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html

ArrayList.addAll() ConcurrentModificationException

I'm facing some really strange problems while implementing a kind of Kademlia bucket in Java 8 (OpenJDK).
I need to get at least a specific number of items from so-called Buckets.
But that's not the problem.
Somehow, I get sometimes a ConcurrentModificationException while doing closest.addAll() on the ArrayList though it is just used in a single thread and I'm not iterating or doing something like that.
Do you know how to help me?
Here is my code (I know it's a mess!):
List<Neighbour> getClosest(Node n, int num) {
ArrayList<Neighbour> closest = new ArrayList<>();
int missing;
int walkDown = n.getBucket(me);
int walkUp = walkDown + 1;
boolean pleaseBreak = true;
while (true) {
missing = num - closest.size();
if (missing <= 0) {
return closest;
}
if (walkUp >= 0 && walkUp < 160) {
List<Neighbour> l = buckets[walkUp].getClosest(missing);
closest.addAll(l);
if (closest.size() >= missing) {
return closest;
}
walkUp++;
pleaseBreak = false;
}
if (walkDown >= 0 && walkDown < 160) {
List<Neighbour> l = buckets[walkDown].getClosest(missing);
closest.addAll(l);
if (closest.size() >= missing) {
return closest;
}
walkDown--;
pleaseBreak = false;
}
if (pleaseBreak) {
return closest;
}
pleaseBreak = true;
}
}
ConcurrentModificationException actually means that you are breaking the rules of iteration by somehow modifying the list while iterating it.
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
That said it is fairly clear what could be causing this issue. As closest is a new List being filled by the method it must be l that is being modified.
There are two options:
Another thread is doing it.
You already have an iterator open across the list l.
Assuming it is not 1 (or you would probably have mentioned that) I will go for:
Your getClosest method is returning a sublist of a list that is being iterated across and/or modified and addAll is also attempting to iterate over it.
To fix, make getClosest return a copy of the sublist.

Broken function even though it appears to be correct

I've been testing my app today and somehow a function broke after I've done a completely unrelated change, and most importantly I can't see why it shouldn't work.
Here it is:
public static int componentStrId(String string)
{
for(int i = 0; i < GameMain.ComponentNames.length; i++)
{
Gdx.app.log("GameCoordinator", "componentStrId index: " + i);
if(string == GameMain.ComponentNames[i])
{
return i;
}
}
return -1;
}
Before you ask, yes, the string I feed it is present in the array I search from, and yet the function returns -1. It just cycles pointlessly through the array.
I've got the feeling that Eclipse freaked out, although maybe I'm just blind and can't see an obvious mistake... So what is it, the former or the latter?
Instead of this ...
if(string == GameMain.ComponentNames[i])
Use this ...
if(string.equals(GameMain.ComponentNames[i]))
If you provide
GameMain.ComponentNames[3]
as parameter it would return 3.
If you construct a String separately it would always return -1, as == would return true only if both references point at the same object.

Null-free "maps": Is a callback solution slower than tryGet()?

In comments to "How to implement List, Set, and Map in null free design?", Steven Sudit and I got into a discussion about using a callback, with handlers for "found" and "not found" situations, vs. a tryGet() method, taking an out parameter and returning a boolean indicating whether the out parameter had been populated. Steven maintained that the callback approach was more complex and almost certain to be slower; I maintained that the complexity was no greater and the performance at worst the same.
But code speaks louder than words, so I thought I'd implement both and see what I got. The original question was fairly theoretical with regard to language ("And for argument sake, let's say this language don't even have null") -- I've used Java here because that's what I've got handy. Java doesn't have out parameters, but it doesn't have first-class functions either, so style-wise, it should suck equally for both approaches.
(Digression: As far as complexity goes: I like the callback design because it inherently forces the user of the API to handle both cases, whereas the tryGet() design requires callers to perform their own boilerplate conditional check, which they could forget or get wrong. But having now implemented both, I can see why the tryGet() design looks simpler, at least in the short term.)
First, the callback example:
class CallbackMap<K, V> {
private final Map<K, V> backingMap;
public CallbackMap(Map<K, V> backingMap) {
this.backingMap = backingMap;
}
void lookup(K key, Callback<K, V> handler) {
V val = backingMap.get(key);
if (val == null) {
handler.handleMissing(key);
} else {
handler.handleFound(key, val);
}
}
}
interface Callback<K, V> {
void handleFound(K key, V value);
void handleMissing(K key);
}
class CallbackExample {
private final Map<String, String> map;
private final List<String> found;
private final List<String> missing;
private Callback<String, String> handler;
public CallbackExample(Map<String, String> map) {
this.map = map;
found = new ArrayList<String>(map.size());
missing = new ArrayList<String>(map.size());
handler = new Callback<String, String>() {
public void handleFound(String key, String value) {
found.add(key + ": " + value);
}
public void handleMissing(String key) {
missing.add(key);
}
};
}
void test() {
CallbackMap<String, String> cbMap = new CallbackMap<String, String>(map);
for (int i = 0, count = map.size(); i < count; i++) {
String key = "key" + i;
cbMap.lookup(key, handler);
}
System.out.println(found.size() + " found");
System.out.println(missing.size() + " missing");
}
}
Now, the tryGet() example -- as best I understand the pattern (and I might well be wrong):
class TryGetMap<K, V> {
private final Map<K, V> backingMap;
public TryGetMap(Map<K, V> backingMap) {
this.backingMap = backingMap;
}
boolean tryGet(K key, OutParameter<V> valueParam) {
V val = backingMap.get(key);
if (val == null) {
return false;
}
valueParam.value = val;
return true;
}
}
class OutParameter<V> {
V value;
}
class TryGetExample {
private final Map<String, String> map;
private final List<String> found;
private final List<String> missing;
private final OutParameter<String> out = new OutParameter<String>();
public TryGetExample(Map<String, String> map) {
this.map = map;
found = new ArrayList<String>(map.size());
missing = new ArrayList<String>(map.size());
}
void test() {
TryGetMap<String, String> tgMap = new TryGetMap<String, String>(map);
for (int i = 0, count = map.size(); i < count; i++) {
String key = "key" + i;
if (tgMap.tryGet(key, out)) {
found.add(key + ": " + out.value);
} else {
missing.add(key);
}
}
System.out.println(found.size() + " found");
System.out.println(missing.size() + " missing");
}
}
And finally, the performance test code:
public static void main(String[] args) {
int size = 200000;
Map<String, String> map = new HashMap<String, String>();
for (int i = 0; i < size; i++) {
String val = (i % 5 == 0) ? null : "value" + i;
map.put("key" + i, val);
}
long totalCallback = 0;
long totalTryGet = 0;
int iterations = 20;
for (int i = 0; i < iterations; i++) {
{
TryGetExample tryGet = new TryGetExample(map);
long tryGetStart = System.currentTimeMillis();
tryGet.test();
totalTryGet += (System.currentTimeMillis() - tryGetStart);
}
System.gc();
{
CallbackExample callback = new CallbackExample(map);
long callbackStart = System.currentTimeMillis();
callback.test();
totalCallback += (System.currentTimeMillis() - callbackStart);
}
System.gc();
}
System.out.println("Avg. callback: " + (totalCallback / iterations));
System.out.println("Avg. tryGet(): " + (totalTryGet / iterations));
}
On my first attempt, I got 50% worse performance for callback than for tryGet(), which really surprised me. But, on a hunch, I added some garbage collection, and the performance penalty vanished.
This fits with my instinct, which is that we're basically talking about taking the same number of method calls, conditional checks, etc. and rearranging them. But then, I wrote the code, so I might well have written a suboptimal or subconsicously penalized tryGet() implementation. Thoughts?
Updated: Per comment from Michael Aaron Safyan, fixed TryGetExample to reuse OutParameter.
I would say that neither design makes sense in practice, regardless of the performance. I would argue that both mechanisms are overly complicated and, more importantly, don't take into account actual usage.
Actual Usage
If a user looks up a value in a map and it isn't there, most likely the user wants one of the following:
To insert some value with that key into the map
To get back some default value
To be informed that the value isn't there
Thus I would argue that a better, null-free API would be:
has(key) which indicates if the key is present (if one only wishes to check for the key's existence).
get(key) which reports the value if the key is present; otherwise, throws NoSuchElementException.
get(key,defaultval) which reports the value for the key, or defaultval if the key isn't present.
setdefault(key,defaultval) which inserts (key,defaultval) if key isn't present, and returns the value associated with key (which is defaultval if there is no previous mapping, otherwise prev mapping).
The only way to get back null is if you explicity ask for it as in get(key,null). This API is incredibly simple, and yet is able to handle the most common map-related tasks (in most use cases that I have encountered).
I should also add that in Java, has() would be called containsKey() while setdefault() would be called putIfAbsent(). Because get() signals an object's absence via a NoSuchElementException, it is then possible to associate a key with null and treat it as a legitimate association.... if get() returns null, it means the key has been associated with the value null, not that the key is absent (although you can define your API to disallow a value of null if you so choose, in which case you would throw an IllegalArgumentException from the functions that are used to add associations if the value given is null). Another advantage to this API, is that setdefault() only needs to perform the lookup procedure once instead of twice, which would be the case if you used if( ! dict.has(key) ){ dict.set(key,val); }. Another advantage is that you do not surprise developers who write something like dict.get(key).doSomething() who assume that get() will always return a non-null object (because they have never inserted a null value into the dictionary)... instead, they get a NoSuchElementException if there is no value for that key, which is more consistent with the rest of the error checking in Java and which is also a much easier to understand and debug than NullPointerException.
Answer To Question
To answer original question, yes, you are unfairly penalizing the tryGet version.... in your callback based mechanism you construct the callback object only once and use it in all subsequent calls; whereas in your tryGet example, you construct your out parameter object in every single iteration. Try taking the line:
OutParameter out = new OutParameter();
Take the line above out of the for-loop and see if that improves the performance of the tryGet example. In other words, place the line above the for-loop, and re-use the out parameter in each iteration.
David, thanks for taking the time to write this up. I'm a C# programmer, so my Java skills are a bit vague these days. Because of this, I decided to port your code over and test it myself. I found some interesting differences and similarities, which are pretty much worth the price of admission as far as I'm concerned. Among the major differences are:
I didn't have to implement TryGet because it's built into Dictionary.
In order to use the native TryGet, instead of inserting nulls to simulate misses, I simply omitted those values. This still means that v = map[k] would have set v to null, so I think it's a proper porting. In hindsight, I could have inserted the nulls and changed (_map.TryGetValue(key, out value)) to (_map.TryGetValue(key, out value) && value != null)), but I'm glad I didn't.
I want to be exceedingly fair. So, to keep the code as compact and maintainable as possible, I used lambda calculus notation, which let me define the callbacks painlessly. This hides much of the complexity of setting up anonymous delegates, and allows me to use closures seamlessly. Ironically, the implementation of Lookup uses TryGet internally.
Instead of declaring a new type of Dictionary, I used an extension method to graft Lookup onto the standard dictionary, much simplifying the code.
With apologies for the less-than-professional quality of the code, here it is:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
static class CallbackDictionary
{
public static void Lookup<K, V>(this Dictionary<K, V> map, K key, Action<K, V> found, Action<K> missed)
{
V v;
if (map.TryGetValue(key, out v))
found(key, v);
else
missed(key);
}
}
class TryGetExample
{
private Dictionary<string, string> _map;
private List<string> _found;
private List<string> _missing;
public TryGetExample(Dictionary<string, string> map)
{
_map = map;
_found = new List<string>(_map.Count);
_missing = new List<string>(_map.Count);
}
public void TestTryGet()
{
for (int i = 0; i < _map.Count; i++)
{
string key = "key" + i;
string value;
if (_map.TryGetValue(key, out value))
_found.Add(key + ": " + value);
else
_missing.Add(key);
}
Console.WriteLine(_found.Count() + " found");
Console.WriteLine(_missing.Count() + " missing");
}
public void TestCallback()
{
for (int i = 0; i < _map.Count; i++)
_map.Lookup("key" + i, (k, v) => _found.Add(k + ": " + v), k => _missing.Add(k));
Console.WriteLine(_found.Count() + " found");
Console.WriteLine(_missing.Count() + " missing");
}
}
class Program
{
static void Main(string[] args)
{
int size = 2000000;
var map = new Dictionary<string, string>(size);
for (int i = 0; i < size; i++)
if (i % 5 != 0)
map.Add("key" + i, "value" + i);
long totalCallback = 0;
long totalTryGet = 0;
int iterations = 20;
TryGetExample tryGet;
for (int i = 0; i < iterations; i++)
{
tryGet = new TryGetExample(map);
long tryGetStart = DateTime.UtcNow.Ticks;
tryGet.TestTryGet();
totalTryGet += (DateTime.UtcNow.Ticks - tryGetStart);
GC.Collect();
tryGet = new TryGetExample(map);
long callbackStart = DateTime.UtcNow.Ticks;
tryGet.TestCallback();
totalCallback += (DateTime.UtcNow.Ticks - callbackStart);
GC.Collect();
}
Console.WriteLine("Avg. callback: " + (totalCallback / iterations));
Console.WriteLine("Avg. tryGet(): " + (totalTryGet / iterations));
}
}
}
My performance expectations, as I said in the article that inspired this one, would be that neither one is much faster or slower than the other. After all, most of the work is in the searching and adding, not in the simple logic that structures it. In fact, it varied a bit among runs, but I was unable to detect any consistent advantage.
Part of the problem is that I used a low-precision timer and the test was short, so I increased the count by 10x to 2000000 and that helped. Now callbacks are about 3% slower, which I do not consider significant. On my fairly slow machine, callbacks took 17773437 while tryget took 17234375.
Now, as for code complexity, it's a bit unfair because TryGet is native, so let's just ignore the fact that I had to add a callback interface. At the calling spot, lambda notation did a great job of hiding the complexity. If anything, it's actually shorter than the if/then/else used in the TryGet version, although I suppose I could have used a ternary operator to make it equally compact.
On the whole, I found the C# to be more elegant, and only some of that is due to my bias as a C# programmer. Mainly, I didn't have to define and implement interfaces, which cut down on the plumbing overhead. I also used pretty standard .NET conventions, which seem to be a bit more streamlined than the sort of style favored in Java.

Categories

Resources