Optional<LocalAssignment> updateWith(ConsumerGroupHeartbeatResponseData.Assignment assignment) {
            // Return if we have an assignment, and it is the same as current assignment; comparison without creating a new collection
            if (localEpoch != NONE_EPOCH) {
                if (partitions.size() == assignment.topicPartitions().size() &&
                    assignment.topicPartitions().stream().allMatch(
                        tp -> partitions.containsKey(tp.topicId()) &&
                            partitions.get(tp.topicId()).size() == tp.partitions().size() &&
                            partitions.get(tp.topicId()).containsAll(tp.partitions()))) {
                    return Optional.empty();
                }
            }

            // Bump local epoch and replace assignment
            long nextLocalEpoch = localEpoch + 1;
            HashMap<Uuid, SortedSet<Integer>> partitions = new HashMap<>();
            assignment.topicPartitions().forEach(topicPartitions ->
                partitions.put(topicPartitions.topicId(), new TreeSet<>(topicPartitions.partitions())));
            return Optional.of(new LocalAssignment(nextLocalEpoch, partitions));

        }
A data structure to represent the current assignment, and current target assignment of a member in a consumer group.

Besides the assigned partitions, it contains a local epoch that is bumped whenever the assignment changes, to ensure
that two assignments with the same partitions but different local epochs are not considered equal.
clients/src/main/java/org/apache/kafka/clients/consumer/internals/MembershipManager.java