diff --git a/src/main/java/com/android/tools/metalava/model/TypeItem.kt b/src/main/java/com/android/tools/metalava/model/TypeItem.kt
index 7ca5ff98dd28d9983281cc3480ec1ab953e42de2..c39e072f7f9d935cd46ad4cf95e14e1e1cf99876 100644
--- a/src/main/java/com/android/tools/metalava/model/TypeItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/TypeItem.kt
@@ -297,5 +297,46 @@ interface TypeItem {
 
             return dimension + base
         }
+
+        /** Compares two strings, ignoring space diffs (spaces, not whitespace in general) */
+        fun equalsWithoutSpace(s1: String, s2: String): Boolean {
+            if (s1 == s2) {
+                return true
+            }
+            val sp1 = s1.indexOf(' ') // first space
+            val sp2 = s2.indexOf(' ')
+            if (sp1 == -1 && sp2 == -1) {
+                // no spaces in strings and aren't equal
+                return false
+            }
+
+            val l1 = s1.length
+            val l2 = s2.length
+            var i1 = 0
+            var i2 = 0
+
+            while (i1 < l1 && i2 < l2) {
+                var c1 = s1[i1++]
+                var c2 = s2[i2++]
+
+                while (c1 == ' ' && i1 < l1) {
+                    c1 = s1[i1++]
+                }
+                while (c2 == ' ' && i2 < l2) {
+                    c2 = s2[i2++]
+                }
+                if (c1 != c2) {
+                    return false
+                }
+            }
+            // Skip trailing spaces
+            while (i1 < l1 && s1[i1] == ' ') {
+                i1++
+            }
+            while (i2 < l2 && s2[i2] == ' ') {
+                i2++
+            }
+            return i1 == l1 && i2 == l2
+        }
     }
 }
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
index ef758ff660a88b602d1b8e738f61ad15f30591c5..306770a675fbde386b4780bf60a18384a403973f 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
@@ -149,7 +149,7 @@ class PsiTypeItem private constructor(private val codebase: PsiBasedCodebase, pr
         if (this === other) return true
 
         return when (other) {
-            is TypeItem -> toTypeString().replace(" ", "") == other.toTypeString().replace(" ", "")
+            is TypeItem -> TypeItem.equalsWithoutSpace(toTypeString(), other.toTypeString())
             else -> false
         }
     }
diff --git a/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt b/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt
index d74415b4461c5605d010933bbc5b839ed2d80bcb..9dae73fcc89188c829ca3c532ae09441b9c7ab52 100644
--- a/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt
@@ -73,20 +73,15 @@ class TextTypeItem(
         if (this === other) return true
 
         return when (other) {
-            is TextTypeItem -> toString() == other.toString()
+            // Note: when we support type-use annotations, this is not safe: there could be a string
+            // literal inside which is significant
+            is TextTypeItem -> TypeItem.equalsWithoutSpace(toString(), other.toString())
             is TypeItem -> {
                 val thisString = toTypeString()
                 val otherString = other.toTypeString()
-                if (thisString == otherString) {
+                if (TypeItem.equalsWithoutSpace(thisString, otherString)) {
                     return true
                 }
-                if (thisString[0] == otherString[0]) {
-                    val thisCondensed = thisString.replace(" ", "")
-                    val otherCondensed = otherString.replace(" ", "")
-                    if (thisCondensed == otherCondensed) {
-                        return true
-                    }
-                }
                 if (thisString.startsWith(JAVA_LANG_PREFIX) && thisString.endsWith(otherString) &&
                     thisString.length == otherString.length + JAVA_LANG_PREFIX.length
                 ) {
diff --git a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
index 819bd2bea2d771830ba4975a22cae9f19422a38c..864429d2a394fba42b2bd1459fd9f412cb588a52 100644
--- a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
+++ b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
@@ -2275,6 +2275,30 @@ CompatibilityCheckTest : DriverTest() {
         )
     }
 
+    @Test
+    fun `Insignificant type formatting differences`() {
+        check(
+            checkCompatibilityApi = """
+                package test.pkg {
+                  public final class UsageStatsManager {
+                    method public java.util.Map<java.lang.String, java.lang.Integer> getAppStandbyBuckets();
+                    method public void setAppStandbyBuckets(java.util.Map<java.lang.String, java.lang.Integer>);
+                    field public java.util.Map<java.lang.String, java.lang.Integer> map;
+                  }
+                }
+                """,
+            signatureSource = """
+                package test.pkg {
+                  public final class UsageStatsManager {
+                    method public java.util.Map<java.lang.String,java.lang.Integer> getAppStandbyBuckets();
+                    method public void setAppStandbyBuckets(java.util.Map<java.lang.String,java.lang.Integer>);
+                    field public java.util.Map<java.lang.String,java.lang.Integer> map;
+                  }
+                }
+                """
+        )
+    }
+
     @Test
     fun `Adding and removing reified`() {
         check(
diff --git a/src/test/java/com/android/tools/metalava/model/TypeItemTest.kt b/src/test/java/com/android/tools/metalava/model/TypeItemTest.kt
index 112d51304ecd3259c62bf39fb117917882a2475e..908248d16452205d0965bc47e8b1899733487d72 100644
--- a/src/test/java/com/android/tools/metalava/model/TypeItemTest.kt
+++ b/src/test/java/com/android/tools/metalava/model/TypeItemTest.kt
@@ -33,4 +33,22 @@ class TypeItemTest {
             "java.util.List<@NonNull java.lang.String>"
         )
     }
+
+    @Test
+    fun testEqualsWithoutSpace() {
+        assertThat(TypeItem.equalsWithoutSpace("", "")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace(" ", "")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("", " ")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace(" ", " ")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("true", "tr ue")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("tr ue", "true")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("true", "true ")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("true ", "true")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("true ", "true")).isTrue()
+        assertThat(TypeItem.equalsWithoutSpace("true", " true")).isTrue()
+
+        assertThat(TypeItem.equalsWithoutSpace("true", "false")).isFalse()
+        assertThat(TypeItem.equalsWithoutSpace("true", " true  false")).isFalse()
+        assertThat(TypeItem.equalsWithoutSpace("false ", "falser")).isFalse()
+    }
 }
\ No newline at end of file