diff --git a/api/net/sf/briar/api/Bytes.java b/api/net/sf/briar/api/Bytes.java
index 77b82c1beb95763c421afc20364f6f6ce3a9f4f0..fe95d75d847a1911bbfd1f95ab79f071c4d75f48 100644
--- a/api/net/sf/briar/api/Bytes.java
+++ b/api/net/sf/briar/api/Bytes.java
@@ -7,6 +7,8 @@ public class Bytes {
 
 	private final byte[] bytes;
 
+	private int hashCode = -1;
+
 	public Bytes(byte[] bytes) {
 		this.bytes = bytes;
 	}
@@ -17,7 +19,10 @@ public class Bytes {
 
 	@Override
 	public int hashCode() {
-		return Arrays.hashCode(bytes);
+		// Thread-safe because if two or more threads check and update the
+		// value, they'll calculate the same value
+		if(hashCode == -1) hashCode = Arrays.hashCode(bytes);
+		return hashCode;
 	}
 
 	@Override
diff --git a/api/net/sf/briar/api/protocol/UniqueId.java b/api/net/sf/briar/api/protocol/UniqueId.java
index 8124ed03f0e930c70d4955c2ac23475a0bf7b5a4..5e1e00246d3a29aa682200db5cecfc09177a2964 100644
--- a/api/net/sf/briar/api/protocol/UniqueId.java
+++ b/api/net/sf/briar/api/protocol/UniqueId.java
@@ -9,6 +9,8 @@ public abstract class UniqueId {
 
 	protected final byte[] id;
 
+	private int hashCode = -1;
+
 	protected UniqueId(byte[] id) {
 		assert id.length == LENGTH;
 		this.id = id;
@@ -20,6 +22,9 @@ public abstract class UniqueId {
 
 	@Override
 	public int hashCode() {
-		return Arrays.hashCode(id);
+		// Thread-safe because if two or more threads check and update the
+		// value, they'll calculate the same value
+		if(hashCode == -1) hashCode = Arrays.hashCode(id);
+		return hashCode;
 	}
 }