2016-01-22 1 views
-1

У меня был вопрос:Почему это работает? (SameAs против ==)

Why is this not working sometimes?

Я сравнивал растровые изображения и выполнения кода соответственно, но код не выполняется. Мой вопрос получил много замечательных ответов. Один из ответов, который работал, предложил удалить == и изменить его на .sameAs(), чтобы мое приложение работало на более новых телефонах.

ClickGround = v.getBackground(); //Get the background of button clicked (ClickGround is a bitmap) 
     BitClick = ((BitmapDrawable) ClickGround).getBitmap(); //the bitmap background of the button clicked 

Итак, почему же используя sameAs() метод работать более эффективно, чем при использовании == для сравнения растровых изображений? Кроме того, почему использование == работает в более низких версиях android (kitkat) и sameAs в более высоких версиях?

Спасибо,

Ruchir

+0

Если вы заметили в связанном вопросе, вы увидите, что в первом ответе говорится о том, как «я сравниваю разные объекты». Зачем? –

ответ

0

Просто чтобы быть ясно, sameAs() не работает «более эффективно», а это только один, который работает правильно/надежно. Это связано с тем, что == решает, совпадают ли два объекта, т. Е. Указывают на один и тот же объект, но могут возвращать значение false даже для растровых изображений, которые являются точно такими же, но могут быть разными объектами.

Методы, которые вы вызываете, могут на определенных устройствах и в рамках договора API возвращать разные объекты для одного и того же растрового изображения, поэтому == вернет false. sameAs() возвращает истину, если битовая карта такая же (как и в идентичны по всем свойствам):

Given another bitmap, return true if it has the same dimensions, config, 
and pixel data as this bitmap. If any of those differ, return false. If 
other is null, return false. 

Это та же идея:

void foo(Integer a, Integer b) { 
    if (a == b) { 
    ... 
    } 
} 

Это почти наверняка неправильно - вы обычно хотите a.equals(b) или, возможно, Objects.equals (а, б) если a может быть пустым, так как в противном случае даже называет как:

foo(1234, 1234)

часто не выдерживает сравнения выше.

+0

Значит, он работает только тогда, когда объекты одного класса? –

+0

Нет. То есть, я не уверен, что вы подразумеваете под «это работает», но это не связано с классом. Хорошее эмпирическое правило состоит в том, что, по крайней мере, пока вы не поймете это хорошо, вы должны почти никогда не использовать '==' для сравнения объектов. Вы почти всегда используете 'equals' или другой сопоставимый метод для определения того, являются ли объекты одинаковыми. В случае Bitmap этот метод является 'sameAs(). – BeeOnRope

+0

Хорошо, позвольте мне перефразировать мой вопрос. Как бы вы определили: «Два объекта идентичны»? –

0

== это оператор отношения и, таким образом, действительно хорош только для числовых значений представителя

Однако sameAs() смотрит на данные, содержащиеся, а не весь файл, и все об этом.

Например:

int a = 3; 
String b = "3"; 

Мы знаем, что 3 является числовым значением и «3» является строка, представляющая числовое значение. Оба они представляют одно и то же для обычного человека, но компьютер. В этом случае, если вы попытаетесь сравнить

if (a==b){//something} 

Мы знаем, что мы должны сделать какой-то перевод, так как два не то же самое к компьютеру.

Что-то вроде

if (Integer.parseInt("b") == a){//do something} 

потребовалось бы или даже

if(Integer.toString(a).equals(b)){//do something) 

В случае образов, две абсолютно разные места и другие ссылки, поэтому они никогда не могли быть «эквивалент» для a == сравнение типов. Даже в обеих строках они имеют разные места, которые хранятся в памяти и разные ассоциативные значения, поэтому используется .equals().

В случае растровых изображений это абстрактный тип данных, поэтому даже equals() здесь не применим. Потому что вам нужно сравнить абстрактные данные, содержащиеся в sameAs().

+0

Тогда, когда я должен использовать 'equals()' over 'sameAs()'? –

+0

Это зависит от класса, о котором идет речь.Лучшей практикой является то, что _value objects_ переопределяет 'equals', чтобы обеспечить более значимое сравнение равенства (в противном случае оно по умолчанию совпадает с идентификатором, которое является таким же, как' == ', как я описал в своем ответе). По какой-то причине класс «Bitmap» Android не переопределяет 'equals()', но вместо этого определяет 'sameAs()' с той же целью. Я не знаю, почему, но вы всегда можете задать новый вопрос. – BeeOnRope

+0

Хорошо помните, что у Android есть интересные вещи вокруг растровых изображений, например, с помощью MediaStore API. Тот же АА() не будет равным «значениям» возврата в этом случае. Он должен фактически «смотреть» на растровое изображение и использовать сравнение sameAsAs, так как они являются абстрактным типом данных, и equals не будут применяться в этих случаях. Примером было действительно сделать его понятым по-человечески. – childofthehorn

0

Так почему же использование метода sameAs() работает более эффективно, чем использование == для сравнения битмапов?

Не работает более эффективно. Когда == работает, он эффективнее, чем sameAs().

Однако sameAs() работает в ситуациях, когда == не работает. Вот почему вы должны использовать sameAs(), а не ==, чтобы сравнить битмапы.

Кроме того, почему использование == работает в более низких версиях android (kitkat) и одинаковых в более высоких версиях?

Что-то о том, что объекты Bitmap создаются и совместно используются (или нет) в новых версиях. Когда вы тестировали с использованием ==, вы полагались на недокументированное поведение конкретной реализации. Это поведение изменилось.

Почему это изменилось? Мой угадывает в том, что это побочный эффект изменения механизма закулисного растрового изображения за кадром.