2015-04-17 15 views
5

Mam dwa obiekty java z polem byte[] o rozmiarze rzędu miliona. Jaki jest najszybszy i najskuteczniejszy sposób sprawdzenia dla tych obiektów java Deep Equal?Jaki jest najszybszy i skuteczny sposób sprawdzania Deep Equal dla dwóch obiektów java?

Próbka Podmiot:

@Entity 
public class NormalBook 
{ 

    @Id 
    private String bookId; 

    @Column 
    private String title; 

    @Column 
    private byte[] pdfFile; 

    //setters and getters 

    } 

Uwaga: Robię to za narzędzie ORM w zasadzie jestem sprawdzanie obiektu (który jest w zarządzanym państwie) z obecnego obiektu w Persistence Context .

+4

Jeśli wykonujesz więcej niż jedno porównanie, prawdopodobnie opłaca się obliczyć sumę kontrolną/kod skrótu dla każdego. – biziclop

+0

Ale to dość dziwna rzecz ... jaki jest rzeczywisty problem, który próbujesz rozwiązać? – biziclop

+0

Jak "obiekt" znalazł się w pliku jar? Czy plik jar zawiera serializowane obiekty java? (Należy pamiętać, że dwa serializowane obiekty Java, które są "equals()" - lub nawet dokładnie to samo wystąpienie - mogą generować inną sekwencję bajtów za każdym razem serializowanym.) – Paul

Odpowiedz

2

Zastąp equals() lub mieć metodę * pomocnika i zrobić to w 5 krokach (bad option!):

1. Check for *not null*. 
2. Check for same *type*. 
3. Check for *size of byte[]*. 
4. Check for `==` (*reference equality* of byte[]) 
5. Start comparing byte values 
+0

Jeśli porównasz wartość bajtu (krok 4), nie sądzisz, że zajmie to dużo czasu dla dużego obiektu? –

+2

@dev Oczywiście czas będzie proporcjonalny do wielkości obiektu. Jakiej innej opcji musisz porównywać inne niż faktyczne porównywanie? –

+1

@dev - Cóż, jeśli chcesz sprawdzić * wartość *, to będziesz musiał to zrobić :). 'Arrays.equals()' obejmie kroki 3, 4 i 5 .. – TheLostMind

0

użyć następujących w definicji equals() w klasie twojego obiektu:

java.util.Arrays.equals(bs1, bs2) 

Możesz również sprawdzić najpierw, czy są to macierze o tej samej nazwie (). Chociaż ta metoda może i tak to zrobić.

Na przykład (i czyniąc pewne założenia dotyczące swojej klasie, która zawiera tablice)

public boolean equals(Object obj) { 
    if(this == obj) 
     return true; 
    if(!(obj instanceof MyObject)) // covers case where obj null, too. 
     return false; 
    return Arrays.equals(this.bytes, ((MyObject)obj).bytes); 
} 

Jeśli istnieją inne pola w swojej klasie, Twój equals() należy wziąć pod uwagę te zbyt.

(Nie może być lepiej odpowiedzieć na pytanie, czy można dostarczyć więcej informacji o jakie dane są przechowywane w tablicach.)

+0

Ya. 'Arrays.equals()' sprawdza referencje najpierw – TheLostMind

+0

Zapisuję plik jar o rozmiarze 20 mb w bajcie []. –

+1

@dev dlaczego zapisujesz plik JAR w bajcie [] ... jaki jest cel? – sgpalit

0

jeśli klasa ma pól jak byte[] można użyć coś jak:

public class MyClass { 


    byte[] a; 

    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     MyClass other = (MyClass) obj; 
     if (!Arrays.equals(a, other.a)) 
      return false; 
     return true; 
    } 


} 

Jeśli troska o wydajność i może zapewnić wyjątkowy hascode (to ważne hascode trzeba być unique), a następnie można po prostu porównywać hascode.

+1

Dobra uwaga. Powinieneś zawsze zaimplementować 'hashCode()', gdy nadpisujesz 'equals()'. – Paul

+0

Jak zapewniłbyś unikalny kod skrótu? Zasadniczo nie możesz. – immibis

+1

Jednak kody skrótu (w języku Java) * nie * muszą być - i zazwyczaj * nie są * - unikalne. (NIE są one identyfikatorami). Poza tym: Raz spędziłem dwa tygodnie na naprawianiu systemu napisanego przez kogoś, kto błędnie wierzył, że kody hash są zawsze unikalne. Jednak zwracane wartości hashCode() powinny być dobrze rozmieszczone. * Efektywna Java * (Joshua Bloch) dostarcza dobrego podsumowania kiedy i jak - przesłonić 'hashCode()'. – Paul

Powiązane problemy