Menu
Coddy logo textTech

Sobrescrita de hashCode e ==

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy. Lição 71 de 110.

Por padrão, dois objetos em Dart são iguais apenas se forem a exata mesma instância na memória. Isso significa que dois objetos com valores idênticos ainda são considerados diferentes:

class Point {
  int x, y;
  Point(this.x, this.y);
}

void main() {
  var p1 = Point(3, 4);
  var p2 = Point(3, 4);
  print(p1 == p2);  // false - instâncias diferentes!
}

Para comparar objetos por seus valores, você precisa sobrescrever tanto o operador == quanto o hashCode. Estes dois devem sempre ser sobrescritos juntos - se dois objetos são iguais, eles devem ter o mesmo hash code:

class Point {
  final int x, y;
  Point(this.x, this.y);
  
  @override
  bool operator ==(Object other) {
    if (other is! Point) return false;
    return x == other.x && y == other.y;
  }
  
  @override
  int get hashCode => Object.hash(x, y);
}

void main() {
  var p1 = Point(3, 4);
  var p2 = Point(3, 4);
  print(p1 == p2);  // true - mesmos valores!
}

O hashCode é crucial para coleções como chaves de Set e Map. O utilitário Object.hash() do Dart combina múltiplos valores em um único código hash. Sem um hashCode adequado, seus objetos não funcionarão corretamente em coleções baseadas em hash, mesmo que o == seja sobrescrito.

challenge icon

Desafio

Fácil

Vamos criar um sistema de coordenadas em que os pontos possam ser comparados por seus valores, e não por seus endereços de memória! Você criará uma classe Coordinate que implementa corretamente a igualdade baseada em valor, fazendo com que ela funcione corretamente com verificações de igualdade e coleções baseadas em hash, como Set.

Você organizará seu código em dois arquivos:

  • coordinate.dart: crie uma classe Coordinate que represente um ponto no espaço 2D com os campos final int x e final int y. Substitua tanto o operador == quanto hashCode para que duas coordenadas com os mesmos valores de x e y sejam consideradas iguais. Use Object.hash() para gerar o código hash a partir de ambos os campos.
  • main.dart: importe seu arquivo de coordenadas e demonstre como a igualdade baseada em valor altera o comportamento da comparação de objetos:
    • crie dois objetos Coordinate separados, ambos com x: 5 e y: 10
    • imprima se eles são iguais usando ==
    • imprima se eles são idênticos (a mesma instância) usando identical()
    • crie um Set<Coordinate> e adicione as duas coordenadas a ele
    • imprima o tamanho do conjunto (deve ser 1, pois elas são iguais!)
    • crie uma terceira coordenada com x: 3 e y: 7 e adicione-a ao conjunto
    • imprima o tamanho final do conjunto

Este desafio demonstra por que hashCode e == devem sempre ser substituídos juntos. O Set usa códigos hash para organizar os elementos; portanto, sem um hashCode adequado, até mesmo objetos iguais podem ser armazenados como duplicatas!

Saída esperada:

true
false
1
2

Experimente você mesmo

import 'coordinate.dart';

void main() {
  // TODO: Crie dois objetos Coordinate separados, ambos com x: 5 e y: 10

  // TODO: Imprima se eles são iguais usando ==

  // TODO: Imprima se eles são idênticos (mesma instância) usando identical()

  // TODO: Crie um Set<Coordinate> e adicione ambas as coordenadas a ele

  // TODO: Imprima o comprimento (length) do conjunto (deve ser 1, já que eles são iguais!)

  // TODO: Crie uma terceira coordenada com x: 3 e y: 7, adicione-a ao conjunto

  // TODO: Imprima o comprimento final do conjunto
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Dart online