Объясните переопределенный метод equal в классе String

В переопределенном методе класса String equal используйте count, value и offset. Что это такое, Почему мы не используем очень простые, например, для подсчета, мы можем использовать функцию length(), значение, которое является массивом, мы можем использовать toCharArray();, а для смещения мы можем взять length()-1. Я пытался найти количество, значение и смещение этих ключевых слов в документации Java, но не нашел....

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
    }

person Guest    schedule 06.12.2016    source источник
comment
Вы смотрели на другие кодовые места в классе String, по моему мнению, значением является массив char, который хранит String как char arr, смещение - это индекс этого char arr, и для его строки просто повторяются символы и проверяется равенство или нет, количество означает длина строки, вы также спрашиваете, почему используется так, я думаю, что использование такой лучшей производительности с помощью метода length () с использованием   -  person Mithat Konuk    schedule 06.12.2016
comment
мы можем использовать toCharArray() - вы действительно хотите создавать новый массив каждый раз, когда вы сравниваете строки? Это звучит как очень, очень плохая идея для меня.   -  person Jon Skeet    schedule 06.12.2016
comment
Не могли бы вы дать ссылку на реализацию, на которую вы смотрите, пожалуйста? Это сильно изменилось вокруг Java 7, обновление 6, IIRC. Я подозреваю, что ваше ожидание использования только length()-1 неверно... но трудно сказать наверняка, не зная, на какую реализацию вы смотрите.   -  person Jon Skeet    schedule 06.12.2016


Ответы (3)


Вот определения:

value  -> array of char holding the chars present in the String
count  -> number of chars in the String
offset -> offset of first character to be considered in the value array

Например, рассмотрим массив

char[] chars = new char[]{'a', 'b', 'c', 'd', 'e'};
String str = new String(chars, 1, 2);
System.out.println(str);   // Prints bc  

char[] chars2 = new char[]{'b', 'c'};
String str2 = new String(chars2, 0, 2);
System.out.println(str2);   // Prints bc

System.out.println(str.equals(str2));  // Prints true  

Вы можете себе представить, что значение равно ['a', 'b', 'c', 'd', 'e'] для String str и ['b', 'c'] для String str2.

Это неправда. Обе строки внутренне используют массив символов размера 2, массив ['b', 'c'].

Но когда вы запрашиваете substring, создается новый String с тем же value и разными значениями offset и count.


Здесь описание value, offset, count с некоторым примером

command                             value           count  offset   toString
---------------------------------------------------------------------------
String str = new String("ABC");     ['A', 'B', 'C']   3      0       ABC
str.substring(2);                   ['A', 'B', 'C']   1      2       C    
str.substring(1, 2);                ['A', 'B', 'C']   2      1       BC
person Davide Lorenzo MARINO    schedule 06.12.2016
comment
спасибо за хорошее объяснение, если мой вопрос правильный, пожалуйста, проголосуйте за него.... - person Guest; 06.12.2016

Из JDK 1.8.0_65 -> java.lang пакета -> String.java класса:

/**
 * Compares this string to the specified object.  The result is {@code
 * true} if and only if the argument is not {@code null} and is a {@code
 * String} object that represents the same sequence of characters as this
 * object.
 *
 * @param  anObject
 *         The object to compare this {@code String} against
 *
 * @return  {@code true} if the given object represents a {@code String}
 *          equivalent to this string, {@code false} otherwise
 *
 * @see  #compareTo(String)
 * @see  #equalsIgnoreCase(String)
 */
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

где value определяется как

/** The value is used for character storage. */
private final char value[];

Так что я надеюсь, что это в значительной степени развеет ваши сомнения.

person Naman    schedule 06.12.2016
comment
Я не понимаю, в чем этот ответ помогает понять, что такое подсчет и смещение. - person Davide Lorenzo MARINO; 06.12.2016
comment
@DavideLorenzoMARINO сама документация объясняет переопределенный метод равенства в классе String, count и offset равны value.length и 0 соответственно. - person Naman; 06.12.2016
comment
Путаница здесь вызвана тем, что OP не указывает версию Java. В частности, изменилась внутренняя реализация String, у OP была старая версия, этот ответ относится к более новой. - person biziclop; 07.12.2016

Поля offset и count используются, поскольку сравниваемое String может быть подстрокой другого String. В этом случае новый объект String не создается, но строка указывает на местоположение в другом String. Вот почему существуют поля count и offset.

Пример:

String s1 = "DoTheHuzzle";
String s2 = s1.subString(2, 5);   // "The"

В этом случае s2 имеет offset из 2 и length из 3.

person Stefan    schedule 06.12.2016
comment
По крайней мере, раньше это было правдой. Я не верю, что это сейчас, поэтому я попросил ОП сослаться на конкретную версию. - person Jon Skeet; 06.12.2016