хэш-код () метод, когда равняется () основан на нескольких независимых полях

Попробуйте этот код:

Sub getRangeAddress()
    Dim oRng As Range
    Set oRng = Evaluate("=INDIRECT(Address(2, 1, , , ""Sheet2""))")
    If oRng.Parent.Name <> ActiveSheet.Name Then
        MsgBox oRng.Address(, , , True)
    End If
End Sub
10
задан 26 January 2009 в 08:22
поделиться

10 ответов

Я не думаю, что нетривиальный хэш-код существует. Кроме того, Ваш equals() нарушает общий контракт, как указано в API---, это не является переходным:

(1,2) равняется (1,3)

(4,3) равняется (1,3)

Но (4,3) не равно (1,2).


Ради полноты я представляю Вам Стрельба по тарелочкамNikoдоказательство - =)

Требование: хэш-код должен быть тривиальной постоянной функцией.

Доказательство: позволить (a,b) и (c,d) будьте двумя объектами с отличными хэш-кодами, т.е. h(a,b) ≠ h(c,d). Рассмотрите объект (a,d). По определению OP, (a,d) равно (a,b), и (a,d) равно (c,d). Это следует из контракта хэш-кода это h(a,d) = h(a,b) = h(c,d); противоречие.

23
ответ дан 3 December 2019 в 14:00
поделиться

Хорошо, в Вашем сценарии, игнорируя требования API в течение секунды, нет никакой непостоянной хеш-функции

Предположите, что был hashfunction, который имеет различные значения для

(a, b), (a, c), b! =c, затем хешируйте (a, b)! = хеш (a, c), eventhough (a, b) = (a, c).

Точно так же (b, a) и (c, a) должен испустить тот же хэш-код.

Давайте назовем нашу хеш-функцию h. Мы находим:

h (x, y) = h (x, w) = h (v, w) forall x, y, v, w.

Следовательно, единственный hashFunction, который делает то, что Вы хотите, является постоянным.

9
ответ дан 3 December 2019 в 14:00
поделиться

Я - право вполне уверенного Zach - нет никакого нетривиального хэш-кода, чтобы сделать это.

Псевдодоказательство:

Рассмотрите любые два неравных значения, X = (id1, name1) и Y = (id2, name2).

Теперь рассмотрите Z = (id2, name1). Это равно обоим X и Y, так должен иметь тот же хэш-код как оба X и Y. Поэтому X и Y должны иметь тот же хэш-код - что означает, что все значения должны иметь тот же хэш-код.

Существует причина, почему Вы вошли в странную ситуацию - Вы повреждаетесь, переходная природа равняется. То, что X.equals (Z) и Z.equals (Y) должен означать, что X.equals (Y) - но он не делает. Ваше определение равенства не подходит для нормального контракта, равняется.

6
ответ дан 3 December 2019 в 14:00
поделиться

Я думаю, что Вы не можете. Причина, Ваш equals() метод не является переходным.

Транзитивность означает для трех непустых указателей x, y, z, если x.equals(y), y.equals(z), затем x.equals(z). В Вашем примере, объекте x={id: 1, name: "ha"}, y={id: 1, name: "foo"}, z={id: 2, name: "bar"} имейте это свойство (x.equals(y) and y.equals(z)). Однако x.equals(z) false. Каждый equals() метод должен иметь это свойство, видеть Java документы API.

Назад к хеш-функциям: Каждая функция приводит к эквивалентности, определенной f(x)==f(y). Это означает, интересно ли Вы по сравнению со значениями функции и хотите, чтобы это возвратило true если x==y (и возможно в других случаях), Вы получите транзитивное отношение, что означает, что необходимо рассмотреть, по крайней мере, переходное закрытие эквивалентности объектов. В Вашем случае переходное закрытие является тривиальным отношением (все равняется чему-либо). Что означает, что Вы не можете отличить различные объекты никакой функцией.

2
ответ дан 3 December 2019 в 14:00
поделиться

Вы намеренно определили равенство как тогда, когда идентификаторы равны, ИЛИ имена равны.. Shouldnt "ИЛИ" быть "И"?

Если Вы имели в виду, "И" затем Ваш хэш-код должен быть вычислен с помощью тот же самый или меньше (но никогда не использовать поля, не используемые, равняется), поля, которыми Вы, равняется ().

Если бы Вы имели в виду "ИЛИ" затем Вы, то r hashgcode не должен включать идентификатор или имя в его вычислении хэш-кода, которое действительно не имеет смысла.

2
ответ дан 3 December 2019 в 14:00
поделиться

Править: Я не считал вопрос тщательно.

--

Я буду использовать банку Ленга свободного городского населения.

XOR членский хэш-код должен работы. Поскольку они должны хэш-код реализаций () и равняются () правильно.

Однако Ваш код может неправильно, если Вы не защищаете свой хэш-код. После того как это было хешировано, это не должно быть изменено. Этому нужно препятствовать быть, происходят.

public hashCode(){
   return new AssertionError();
}

или

 public class MyClass {
   final int id;
   final String name;
   // constructor
 }

или

public class MyClass {
   private int id;
   private String name;
   boolean hashed=false;
   public void setId(int value){
     if(hashed)throw new IllegalStateException();
     this.id=value;
   }
   public void setName(String value){
     if(hashed)throw new IllegalStateException();
     this.name=value;
   }
   // your equals() here
   public hashCode(){
     hashed=true;
     return new HashCodeBuilder().append(id).append(name).toHashCode();
   }
}
0
ответ дан 3 December 2019 в 14:00
поделиться

Самый простой маршрут является к XOR хэш-кодами каждого отдельного поля. Это имеет незначительное уродство в некоторых ситуациях (например, в X, Y координаты, оно вызывает потенциально плохую ситуацию наличия равных хешей при зеркальном отражении X и Y) но является в целом довольно эффективным. Настройте по мере необходимости для сокращения коллизий при необходимости для эффективности.

-1
ответ дан 3 December 2019 в 14:00
поделиться

Как насчет

public override int GetHashCode()
{
    return id.GetHashCode() ^ name.GetHashCode();
}
-2
ответ дан 3 December 2019 в 14:00
поделиться

Как насчет этого

public override int GetHashCode()
{
    return (id.ToString() + name.ToString()).GetHashCode();
}

Функция должна всегда возвращать "допустимый" хеш...

Править: просто замеченный, что Вы используете "или" не "и" :P хорошо я сомневаюсь, что существует любое хорошее решение этой проблемы...

-1
ответ дан 3 December 2019 в 14:00
поделиться

После того, как перечитано вопрос.

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

--

Править: В моем коде может быть сказан лучше затем мой английский язык.

void setName(String value){
  this.id=Lookup.IDbyName(value);
}
void setID(String value){
  this.name=Lookup.NamebyId(value);
}

РЕДАКТИРОВАНИЕ 2:

Код вопроса может неправильно, как будет всегда возвращать true, если Вы не установили обоих идентификатор и имя.

Если Вы действительно хотите метод, которые делают неравнодушный, равняется, создайте Вас, владеют API, который назвал "partialEquals ()".

0
ответ дан 3 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: