Добавление к ответу @Lombo
Когда вам нужно переопределить equals ()?
По умолчанию реализация equals () объекта равна
public boolean equals(Object obj) {
return (this == obj);
}
, что означает, что два объекта будут считаться равными, только если они имеют одинаковый адрес памяти, который будет истинным, только если вы сравниваете объект с самим собой.
Но вы можете хотите рассмотреть два объекта одинаково, если они имеют одно и то же значение для одного или нескольких своих свойств (см. пример, приведенный в ответе @Lombo).
Итак, вы переопределите equals()
в этих ситуациях, и вы дадите свои собственные условия для равенства.
Я успешно применил equals (), и он отлично работает. Так почему же они просят переопределить hashCode ()?
Хорошо. Пока вы не используете «Коллекции на основе хэша» определенный класс, это нормально. Но в будущем вы можете захотеть использовать HashMap
или HashSet
, и если вы не override
и «правильно реализуете» hashCode () , эта коллекция на основе хэша не будет
Только переопределение равно (добавление к ответу @Lombo)
myMap.put(first,someValue)
myMap.contains(second); --> But it should be the same since the key are the same.But returns false!!! How?
Прежде всего, HashMap проверяет, является ли хэш-код second
совпадает с first
.
Но здесь hashCode отличается для этих двух объектов (потому что у них есть другой адрес памяти - от реализации по умолчанию). Если только значения совпадают, он будет проверять равенство в том же ведре.
Поэтому даже не стоит проверять равенство.
Если у вас есть точка останова внутри вашего переопределенного метода equals (), она не будет входить, если у них разные хэш-коды. contains()
проверяет hashCode()
, и только если они одинаковы, он будет вызывать ваш метод equals()
.
Почему мы не можем сделать проверку HashMap равным во всех ведрах? Поэтому мне не нужно переопределять hashCode () !!
Тогда вам не хватает точки из Hash-based Collections. Рассмотрим следующее:
Your hashCode() implementation : intObject%9.
Ниже приведены ключи, хранящиеся в форме ведер.
Bucket 1 : 1,10,19,... (in thousands)
Bucket 2 : 2,20,29...
Bucket 3 : 3,21,30,...
...
Скажите, вы хотите знать, содержит ли карта ключ 10. Вы хотите найти все ведра? или Вы хотите искать только одно ведро?
На основании hashCode вы бы определили, что если 10 присутствует, он должен присутствовать в Bucket 1. Таким образом, будет поиск только Bucket 1 !!
Связность P2P в двух словах. Предположим, мы говорим о UDP здесь. Следующие шаги также могут применяться к TCP с некоторыми настройками.
** - обычно лучше всего не делать этого полагаться на хорошо известный порт для клиентов P2P. Поскольку два клиента за одним и тем же NAT или брандмауэром вряд ли смогут использовать ваше программное обеспечение в то же время.
Ниже приведен краткий обзор некоторых технологий для изучения.
STUN - простой сервер и протокол для клиентов за NAT / маршрутом, чтобы узнать, каковы их внешние сопоставления IP и портов.
TURN - это расширение для STUN, но поддерживает ретрансляцию для сценариев подключения P2P, где брандмауэры и NAT предотвращают прямые подключения.
ICE - это набор шагов, с помощью которых STUN и TURN используются для настройки соединения P2P , ICE является формальным протоколом для шагов 1-5 выше. Два превосходных набора слайдов на ICE здесь здесь и здесь .
WebRTC является вариантом стандарта ICE в качестве справочной библиотеки для создания сеансов P2P с помощью STUN и TURN.
UPNP + Протокол интернет-шлюза - Некоторые маршрутизаторы поддерживают это для хостов для автоматического получения сопоставлений портов.
libnice - это библиотека C с открытым исходным кодом для Linux (и может работать на Windows), которая реализует ICE.
libjingle - еще одна реализация ICE ( в C ++) из Google. Для Windows и Linux.
PJNATH - это библиотека в наборе библиотек кодирования PJSIP . Это хорошая реализация стека ICE (код C) и была перенесена на множество платформ. (Windows, Linux, Mac, iOS, Symbian и вскоре Android).
И, наконец, у меня есть вопиющий штепсель для вас, чтобы использовать мою базу кода сервера STUN .
Я бы использовал технологию WebRTC в качестве платформы с открытым исходным кодом для такого приложения.
На самом деле это проект с открытым исходным кодом, который поддерживает все необходимые для одноранговых технологий из коробки:
В некоторых случаях есть решения, см. UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal
Мой домашний маршрутизатор позволяет это, в основном, NAT может быть настроен автоматически с помощью соответствующего запроса с компьютера.
Я бы не стал рассчитывать на это, чтобы обеспечить значительное улучшение вашей доступности, поскольку не так много маршрутизаторов поддерживают и поддерживают его.
EDIT: @David предложил этот вопрос SO для библиотеки .NET для UPnP: Есть ли библиотека UPnP для .NET (C # или VB.NET)?
У вас есть еще одна опция, которая является Протокол сопоставления NAT-портов (NAT-PMP) NAT-PMP широко используется приложениями VoIP, такими как клиенты Skype или BitTorrent P2P.
Это может быть немного сложнее, чем то, что вы ищете, но TCP Hole Punching - это метод, который должен работать. http://en.wikipedia.org/wiki/TCP_hole_punching
В качестве альтернативы UPnP отлично работает для маршрутизаторов / брандмауэров, которые его поддерживают.