UndefinedEquals
This type is not guaranteed to implement a useful #equals method.

Severity
WARNING

The problem

This code uses Object.equals (or similar method) with a type that does not have well-defined equals behavior: Collection, Iterable, Multimap, Queue, or CharSequence. Such a call to equals may return false in cases where equality was expected. SparseArray and LongSparseArray do not implement equals, so will fall back to reference equality.

For Collection or Iterable

Your code might be working correctly, but only if there is some subtype of Iterable which does have well-defined equals behavior, and you are certain that both operands are definitely of that type at runtime. (The common examples of such types are [List], [Set], and Multiset, or any subtypes of those.)

If this describes your situation, congratulations: you don’t have a bug. To make this warning go away, change the references in your code to be of that more specific static type, not Collection or Iterable. This lets the bug checker (and human readers) know that there is no risk of a false negative.

The minimal solution is to cast or copy “just in time” before calling equals, but ideally you can make broader changes, to adopt the proper interface more widely in your code.

On the other hand, if you might be mixing a List and a non-List, etc., you are at risk. If you can’t correct that situation, one alternative solution is to use Iterables.elementsEqual (which checks for order-dependent equality, like List.equals).

For Multimap

The discussion above generally applies in this case as well; the well-behaved subtypes to choose from are ListMultimap and SetMultimap.

There is no equivalent to Iterables.elementsEqual in this case, however.

For Queue

All known Queue implementations besides LinkedList use reference equality instead of value-based equality. Some of the workarounds discussed above may apply.

For CharSequence

When comparing a String to a CharSequence, prefer String#contentEquals. When comparing the content of two CharSequences, you may want to compare the string representation: lhs.toString().contentEquals(rhs).

For SparseArray and LongSparseArray

These must be iterated over and compared manually, element by element.

For java.util.Date

Subtypes of Date (like java.sql.Timestamp) break substitutability, so comparing Dates with equals is unreliable.

TIP: java.util.Date is a legacy, bug-prone API. Prefer java.time.Instant or java.time.LocalDateTime.

For ImmutableCollection

Prefer subtypes such as ImmutableSet or ImmutableList, which have well-defined equals.

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("UndefinedEquals") to the enclosing element.