I have a list of models (DocumentSnapshot from Firestore
) that have an id (String).
I need to create a notification for each of them, they could be many (messages from a chat) and I need to use an int id to assign to the notification.
I need to use their String id since I could receive an updated version of that model, so I want to update the notification front that precise model.
What could be a solution?

- 590
- 1
- 8
- 18
-
3Use String hashcode – Greggz Dec 29 '17 at 13:25
-
Do you want to turn a string to an int? I don't understand you. – Joza100 Dec 29 '17 at 13:41
4 Answers
There is inpossible to produce unique int id from infinite set of Strings. But you can use a good hash function for your purpose - in most cases it would be good enough. Please consider using something better than common #hashCode implementation. I would suggest you to look into https://github.com/google/guava/wiki/HashingExplained
and use at least murmur3 algorithm. The code snippet looks like:
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
public class Main {
public static void main(String[] args) {
System.out.println(
Hashing.murmur3_32()
.newHasher()
.putString("Some Sting", Charsets.UTF_8)
.hash().asInt());
}
}

- 91
- 4
-
Yes I know, but I want reduce at the minium the possibility of duplicates. It was easier with Realtime Database, where id was generated basing on the time, but now, with Firestore, they are completely random. – 4face Dec 29 '17 at 17:29
Do it like this
int uniqueNumber = myString.hashCode()

- 1,873
- 1
- 12
- 31
-
The `hashCode` generated by `String.hashCode()` is not that good that you won't hit collisions easily. Better to use a good cryptographic hash code. – Mark Rotteveel Dec 29 '17 at 19:20
-
1
Thanks to I found best solution as:
public static int hashCode(String string) {
return Hashing.murmur3_32()
.newHasher()
.putString(string, Charsets.UTF_8)
.asInt());
}
Or, with String.hashCode()
Thanks to Greggz & navy1978:
public static int hashCode(String string) {
return string != null ? string.hashCode() * PRIME : 0; // PRIME = 31 or another prime number.
}
or this for a @NonNull
value
public static int hashCode(@NonNull String string) {
return string.hashCode() * PRIME; // PRIME = 31 or another prime number.
}

- 590
- 1
- 8
- 18
-
-
-
-
I didn't know when it could return 0, I've just copied from navy example :) thanks – 4face Dec 29 '17 at 18:31
You can try, as Greggz has already suggested, to use the hashCode, Eclipse, for instance, suggests this implementation (where the variable "b" is your String):
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
Of course you can change/adapt it to your needs...

- 1,411
- 1
- 15
- 35
-
Thanks, I didn't know about HashCode, but why add 1 and multiply for 31? – 4face Dec 29 '17 at 13:46
-
1short answer: it's about convention, long answer: We add 1 because we want a non-zero value, and 31 is an arbitrary prime number, you can use another one if you like. If you want to have more info about that, you can have a look here: https://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode – navy1978 Dec 29 '17 at 13:53
-
Would not be better to do: int result = string.hashCode(); result = result != 0 ? result : 1; return result * 31; ? – 4face Dec 29 '17 at 14:01
-
You can play with it, but be careful, string.hasCode() can throw an Exception if string is null... that's why in my answer you have (b==null)? 0: b.hashCode(), remember that in my example b is your string... – navy1978 Dec 29 '17 at 14:04
-
Yes, of course I would also handle that, but also DocumentSnapshot.getId() returns a NonNull value – 4face Dec 29 '17 at 14:07
-
1Ah Ok, it depends on how the original String is generated, in your implementation you have a not-null one, but I was speaking more generally... – navy1978 Dec 29 '17 at 14:10