Ну так нечестно - Java (код внутри)
От: Аноним  
Дата: 28.12.07 18:42
Оценка: +1
int []a={1};
int []a1={1};
System.out.println( a.equals(a1) ); <--- false
System.out.println( Arrays.equals(a,a1) ); <--- true

где справедливость?
Re: Ну так нечестно - Java (код внутри)
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 28.12.07 19:00
Оценка: -2
Здравствуйте, <Аноним>, Вы писали:

А>Re: Ну так нечестно — Java (код внутри)

Все честно: сурово и сердито. Так-то это азы: надо отличать сравнение ссылок на объекты и сравнение внутренних структур объектов.

А>int []a={1};

А>int []a1={1};
А>System.out.println( a.equals(a1) ); <--- false
Массивы — это обычные объекты, потому см. java.lang.Object:
/**
 * Indicates whether some other object is "equal to" this one.
 * <p>
 * The <code>equals</code> method implements an equivalence relation
 * on non-null object references:
 * <ul>
 * <li>It is <i>reflexive</i>: for any non-null reference value
 * <code>x</code>, <code>x.equals(x)</code> should return
 * <code>true</code>.
 * <li>It is <i>symmetric</i>: for any non-null reference values
 * <code>x</code> and <code>y</code>, <code>x.equals(y)</code>
 * should return <code>true</code> if and only if
 * <code>y.equals(x)</code> returns <code>true</code>.
 * <li>It is <i>transitive</i>: for any non-null reference values
 * <code>x</code>, <code>y</code>, and <code>z</code>, if
 * <code>x.equals(y)</code> returns <code>true</code> and
 * <code>y.equals(z)</code> returns <code>true</code>, then
 * <code>x.equals(z)</code> should return <code>true</code>.
 * <li>It is <i>consistent</i>: for any non-null reference values
 * <code>x</code> and <code>y</code>, multiple invocations of
 * <tt>x.equals(y)</tt> consistently return <code>true</code>
 * or consistently return <code>false</code>, provided no
 * information used in <code>equals</code> comparisons on the
 * objects is modified.
 * <li>For any non-null reference value <code>x</code>,
 * <code>x.equals(null)</code> should return <code>false</code>.
 * </ul>
 * <p>
 * The <tt>equals</tt> method for class <code>Object</code> implements 
 * the most discriminating possible equivalence relation on objects; 
 * that is, for any non-null reference values <code>x</code> and
 * <code>y</code>, this method returns <code>true</code> if and only
 * if <code>x</code> and <code>y</code> refer to the same object
 * (<code>x == y</code> has the value <code>true</code>).
 * <p>
 * Note that it is generally necessary to override the <tt>hashCode</tt>
 * method whenever this method is overridden, so as to maintain the
 * general contract for the <tt>hashCode</tt> method, which states
 * that equal objects must have equal hash codes. 
 *
 * @param obj the reference object with which to compare.
 * @return <code>true</code> if this object is the same as the obj
 * argument; <code>false</code> otherwise.
 * @see #hashCode()
 * @see java.util.Hashtable
 */
public boolean equals(Object obj) {
    return (this == obj);
}

А>System.out.println( Arrays.equals(a,a1) ); <--- true
См. java.utils.Arrays:
/**
 * Returns <tt>true</tt> if the two specified arrays of ints are
 * <i>equal</i> to one another. Two arrays are considered equal if both
 * arrays contain the same number of elements, and all corresponding pairs
 * of elements in the two arrays are equal. In other words, two arrays
 * are equal if they contain the same elements in the same order. Also,
 * two array references are considered equal if both are <tt>null</tt>.<p>
 *
 * @param a one array to be tested for equality
 * @param a2 the other array to be tested for equality
 * @return <tt>true</tt> if the two arrays are equal
 */
public static boolean equals(int[] a, int[] a2) {
    if (a==a2)
        return true;
    if (a==null || a2==null)
        return false;
    int length = a.length;
    if (a2.length != length)
        return false;
    for (int i=0; i<length; i++)
        if (a[i] != a2[i])
            return false;
    return true;
}

А>где справедливость?
На месте.
Re: Ну так нечестно - Java (код внутри)
От: aefimov Россия
Дата: 28.12.07 19:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>где справедливость?


В JLS.
Re: Ну так нечестно - Java (код внутри)
От: Аноним  
Дата: 28.12.07 19:35
Оценка:
ну и где нечестно??? в a.equals(a1) сравниваются просто ссылки, Arrays.equals(a,a1) сравниваются уже !массивы! — сначала сравниваются ссылки, затем если нужно — длины, и в итоге — элементы попарно.
Re[2]: Ну так нечестно - Java (код внутри)
От: Аноним  
Дата: 28.12.07 19:40
Оценка:
Здравствуйте, rsn81, Вы писали:

Я думал сравниваются данные в обьекте — здесь это 1 и 1.
Я же не сравниваю ссылки "а" с "а1".
Если
String s=new String("str");
String s1=new String("str");
то equals величины которые обьект в себе хранит
Re[3]: Ну так нечестно - Java (код внутри)
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 28.12.07 19:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Я думал сравниваются данные в обьекте — здесь это 1 и 1.

А вы не думайте (это не всегда полезно), а читайте Javadoc — там же все это написано английским языком, или смотрите исходники, или, как вам посоветовали, читайте JSL (Java Specification Language). Нашел тут достаточно нормальный перевод JSL, правда не последней редакции, кому интересно, дам ссылку.

А>Я же не сравниваю ссылки "а" с "а1".

Если вы пользуетесь методом equals объекта java.lang.Object, то вы тут не при чем: это он всю малину портит.

А>Если

А>String s=new String("str");
А>String s1=new String("str");
А>то equals величины которые обьект в себе хранит
А заглянуть в исходник java.lang.String вам кто мешает? И увидеть, что класс String переопределяет наследованный от Object метод equals.
Re[4]: Ну так нечестно - Java (код внутри)
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 28.12.07 19:52
Оценка:
Здравствуйте, rsn81, Вы писали:

R>А вы не думайте (это не всегда полезно), а читайте Javadoc — там же все это написано английским языком, или смотрите исходники, или, как вам посоветовали, читайте JSL (Java Specification Language). Нашел тут достаточно нормальный перевод JSL, правда не последней редакции, кому интересно, дам ссылку.

Тьфу, бес попутал... JLS, а не JSL.
Re: Ну так нечестно - Java (код внутри)
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 28.12.07 21:03
Оценка: 7 (2) +2
Здравствуйте, Аноним, Вы писали:

А>int []a={1};

А>int []a1={1};
А>System.out.println( a.equals(a1) ); <--- false
А>System.out.println( Arrays.equals(a,a1) ); <--- true

А>где справедливость?


Да, с точки зрения логики это неправильно. К сожалению, в джаве многие вещи (в т.ч. базовые) не реализованы так, как должно/не реализованы вообще. Плюс Sun очень заботится об обратной совместимости, т.о. баги, присутствующие в начальной реализации просто не фиксятся в новых версиях, чтобы не сломать существующий код. Это можно считать минусом, можно считать плюсом, в любом случае это надо принять как данность и просто знать такие моменты (напарываться на баги и узнавать о них).
Идеального продукта не существует, на то он и идеальный. У джавы имхо есть много плюсов, которые перевешивают минусы, в т.ч. и упоминаемый
http://denis-zhdanov.blogspot.com
Re[2]: Ну так нечестно - Java (код внутри)
От: LeonidV Ниоткуда http://vygovskiy.com
Дата: 28.12.07 23:08
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:
DZ>Да, с точки зрения логики это неправильно.

Не вижу никакой не правильности с точки зрения логики. Существуют два указателя на разные объекты. Почему они должны быть равны? Существует метод, сравнивает два массива. Естественно, что для массивов с одинаковыми значениями примитивных типов должны быть равны. Все логично, понятно, и даже вроде как удобно.
http://jvmmemory.com — простой способ настройки JVM
Re[3]: Ну так нечестно - Java (код внутри)
От: joybell0  
Дата: 29.12.07 00:29
Оценка: 2 (2)
Здравствуйте, LeonidV, Вы писали:

LV>Не вижу никакой не правильности с точки зрения логики. Существуют два указателя на разные объекты. Почему они должны быть равны?

Ну а не смущает, что
new Integer(1).equals(new Integer(1)) == true

?
Тоже два указателя на разные объекты.
equals, как правило, проверяет логическое равенство объектов. А для того, чтобы сравнить ссылки, всегда есть оператор == . Поэтому не вижу причины, по которой equals для массивов не мог бы делать то, что сейчас делает Arrays.equals
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Ну так нечестно - Java (код внутри)
От: leska http://highprog.com
Дата: 29.12.07 00:45
Оценка:
Здравствуйте, rsn81, Вы писали:

R>А вы не думайте (это не всегда полезно), а читайте Javadoc — там же все это написано английским языком, или смотрите исходники, или, как вам посоветовали, читайте JSL (Java Specification Language). Нашел тут достаточно нормальный перевод JSL, правда не последней редакции, кому интересно, дам ссылку.


Дайте.

А>>Я же не сравниваю ссылки "а" с "а1".

R>А заглянуть в исходник java.lang.String вам кто мешает? И увидеть, что класс String переопределяет наследованный от Object метод equals.

Вся в этом и беда. Чтобы быть уверенным -- надо заглянуть. Наверное, немного напряжно держать в памяти реализации методов equals наиболее часто используемых классов. Да и не понятно зачем. Можно ведь было сначала договориться, что equals — это логическое сравнение. А == сравнивает ссылки.
Кризис добрался и до IT? Узнай как стать фрилансером.
Re[3]: Ну так нечестно - Java (код внутри)
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 29.12.07 07:00
Оценка:
Здравствуйте, LeonidV, Вы писали:

LV>Не вижу никакой не правильности с точки зрения логики. Существуют два указателя на разные объекты. Почему они должны быть равны? Существует метод, сравнивает два массива. Естественно, что для массивов с одинаковыми значениями примитивных типов должны быть равны. Все логично, понятно, и даже вроде как удобно.


Потому что сравнение ссылок — comparison by identity, конракт метода equals()comparison by equivalence (при этом результат выполнения сравннеия через == может не совпадать с результатом сравнения через equals()).
Пример:

public class CCC {
    public static void main(String[] args) throws Exception {
        String s1 = new String("a");
        String s2 = new String("a");
        System.out.println("==: " + (s1 == s2)); // prints false
        System.out.println("equals(): " + s1.equals(s2)); // print true
    }
}


Автор топика не говорит, что беда в том, что массивы не равны через ==, он говорит, что они не равны через equals(). По мне так вполне логично было бы реализовать массивы с переопределенным equals(), который проводил бы именно comparison by equivalence
http://denis-zhdanov.blogspot.com
Re[5]: Ну так нечестно - Java (код внутри)
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 29.12.07 07:04
Оценка:
Здравствуйте, leska, Вы писали:

L>Дайте.

Было здесь: Спецификация языка Ява — сейчас чего-то не открывается.

L>Вся в этом и беда. Чтобы быть уверенным -- надо заглянуть. Наверное, немного напряжно держать в памяти реализации методов equals наиболее часто используемых классов.

Это абсолютно нормально. Вы держите в голове много действительно ненужной ерунды, понапиханной туда учителями, родителями и другими — в каком году Владимир крестил Русь, как звали попугая Робинзона Крузо и т.п. В отличие от этих знаний сомнительного предназначения, держать в памяти азы своей профессии очень выгодно: работа спорится, зарплата/карьера постоянно растет.

L>Да и не понятно зачем. Можно ведь было сначала договориться, что equals — это логическое сравнение. А == сравнивает ссылки.

RTFM.
Re[4]: Ну так нечестно - Java (код внутри)
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 29.12.07 07:15
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Автор топика не говорит, что беда в том, что массивы не равны через ==, он говорит, что они не равны через equals(). По мне так вполне логично было бы реализовать массивы с переопределенным equals(), который проводил бы именно comparison by equivalence

Тогда наверно надо начать с претензии: почему нет java.lang.Array<T>, как это например сделали в Scala.
Re[4]: Ну так нечестно - Java (код внутри)
От: LeonidV Ниоткуда http://vygovskiy.com
Дата: 29.12.07 08:09
Оценка:
DZ>Автор топика не говорит, что беда в том, что массивы не равны через ==, он говорит, что они не равны через equals(). По мне так вполне логично было бы реализовать массивы с переопределенным equals(), который проводил бы именно comparison by equivalence
Все, понял. Не внимательно топик прочитал.
http://jvmmemory.com — простой способ настройки JVM
Re[6]: Ну так нечестно - Java (код внутри)
От: leska http://highprog.com
Дата: 29.12.07 09:01
Оценка: +1
Здравствуйте, rsn81, Вы писали:

R>Здравствуйте, leska, Вы писали:


R>Это абсолютно нормально. Вы держите в голове много действительно ненужной ерунды, понапиханной туда учителями, родителями и другими — в каком году Владимир крестил Русь, как звали попугая Робинзона Крузо и т.п.

Да, только я не испытываю неудобства от того, что не помню всей этой ерунды.

R>В отличие от этих знаний сомнительного предназначения, держать в памяти азы своей профессии очень выгодно: работа спорится, зарплата/карьера постоянно растет.


Я ж не спорю, я про то, что можно было бы в свое время эти азы сделать немного проще...
Кризис добрался и до IT? Узнай как стать фрилансером.
Re[7]: Ну так нечестно - Java (код внутри)
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 29.12.07 09:14
Оценка:
Здравствуйте, leska, Вы писали:

L>Да, только я не испытываю неудобства от того, что не помню всей этой ерунды.



L>Я ж не спорю, я про то, что можно было бы в свое время эти азы сделать немного проще...

Если вы действительно так считаете, то посмотрите Scala.
Re[4]: Ну так нечестно - Java (код внутри)
От: TNL  
Дата: 29.12.07 09:27
Оценка: -1
Здравствуйте, joybell0, Вы писали:

J>Здравствуйте, LeonidV, Вы писали:


LV>>Не вижу никакой не правильности с точки зрения логики. Существуют два указателя на разные объекты. Почему они должны быть равны?

J>Ну а не смущает, что
J>
J>new Integer(1).equals(new Integer(1)) == true
J>

J>?

А почему это должно смущать?

J>Тоже два указателя на разные объекты.


Нет, это два указателя на один объект. Неизменяемый. Размещенный в пуле объектов.
Все целочисленные типы-обертки для чисел меньше 128 используют пул.
Так же пул используется для строк, данных в кавычках.

J>equals, как правило, проверяет логическое равенство объектов. А для того, чтобы сравнить ссылки, всегда есть оператор == . Поэтому не вижу причины, по которой equals для массивов не мог бы делать то, что сейчас делает Arrays.equals


А зачем усложнять класс массива утилитарными операциями, которые не требуют доступа к "внутренностям" класса и, к тому же, используются не часто? Вот их и вынесли в пакет java.util.
Re[5]: Ну так нечестно - Java (код внутри)
От: elmal  
Дата: 29.12.07 09:42
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Тогда наверно надо начать с претензии: почему нет java.lang.Array<T>, как это например сделали в Scala.

Есть ArrayList<T> . Какие могут быть претензии .
А вообще, я уж забыл, когда массивами в чистом виде последний раз пользовался (в любом языке программирования), только если передавать куда-то в качестве параметров массив надо. Если надо массив использовать — приходится вспоминать синтаксис, забываю .
Интересно, это у меня только так?
Re[5]: Ну так нечестно - Java (код внутри)
От: aefimov Россия
Дата: 29.12.07 09:58
Оценка: 1 (1) +1
Здравствуйте, TNL, Вы писали:

J>>Тоже два указателя на разные объекты.


TNL>Нет, это два указателя на один объект. Неизменяемый. Размещенный в пуле объектов.

TNL>Все целочисленные типы-обертки для чисел меньше 128 используют пул.
TNL>Так же пул используется для строк, данных в кавычках.

Вы все перепутали. Это два разных объекта. И это гарантируется оператором new.
Пул используется для автобоксинга, но там не new, а valueOf
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.