Обратите внимание, что equal_range(k)
возвращает диапазон (пара итераторов в этом контексте), поскольку он опирается на тот факт, что элементы, ключ которых равен k
, хранятся рядом вдоль последовательности контейнера: [1116 ]
С другой стороны, элементы, ключ которых не не равен k
, не являются смежными, но принадлежат в двух непересекающихся диапазонах:
Таким образом, equal_range
невозможно повернуть, чтобы вернуть эту пару диапазонов. Если вам абсолютно необходимо рассматривать два диапазона как один логический диапазон, вы можете прибегнуть к Boost.Range's join
:
template
auto not_equal_range(const Container& c,const Key& k)
{
auto rng=c.equal_range(k);
return boost::range::join(
boost::make_iterator_range(c.begin(),rng.first),
boost::make_iterator_range(rng.second,c.end()));
}
Полный пример приведен ниже.
Live On Coliru kbd>
#include
#include
#include
#include
#include
template
auto not_equal_range(const Container& c,const Key& k)
{
auto rng=c.equal_range(k);
return boost::range::join(
boost::make_iterator_range(c.begin(),rng.first),
boost::make_iterator_range(rng.second,c.end()));
}
using namespace boost::multi_index;
using container=multi_index_container<
int,
indexed_by<
hashed_non_unique>
>
>;
#include
int main()
{
container c={0,0,1,1,2,2,3,4,4,4,5,6,6,6,7};
for(auto x:not_equal_range(c,4))std::cout<
Выходные данные
0 0 1 1 2 2 3 5 6 6 6 7
One thing to consider: testing an object's conformance to the equals contract should involve instances of other types. In particular, problems are likely to appear with instances of a subclass or superclass. Joshua Bloch gives an excellent explanation of the related pitfalls in Effective Java (I'm reusing duffymo's link, so he should get credit for it) -- see the section under Transitivity involving the Point and ColorPoint classes.
True, your implementation doesn't prevent someone from writing a test that involves instances of a subclass, but because ObjectTest
is a generic class it gives the impression that all data points should come from a single class (the class being tested). It might be better to remove the type parameter altogether. Just food for thought.
Джошуа Блох излагает контракт на хеш-код и равен в главе 3 «Эффективной Java» . Похоже, ты многое рассказал. Проверьте документ, чтобы увидеть, пропустил ли я что-нибудь.
Возможно, я что-то упускаю, но на самом деле тест equalsIsSymmetric правильно проверяется только в том случае, если у вас есть точки данных с одинаковыми значениями (например, String a = "a"; String a2 = "а";) В противном случае этот тест выполняется только тогда, когда 2 параметра являются одним экземпляром (т.е. equalsIsSymmetric (a, a);). Фактически, вы снова проверяете, подчиняются ли равные «отражающему» требованию, а не симметричному требованию.
Теорема notEqualsWorks(Object x, Object y) ложна: два разных экземпляра все еще могут быть логически равны согласно их методу equals; вы предполагаете, что экземпляры логически различны, если они являются разными ссылками.
Используя ваш собственный пример выше, две различные точки данных ниже (a != a2) тем не менее равны, но не проходят тест notEqualsWorks:
@DataPoint
public static String a = "a";
@DataPoint
public static String a2 = new String("a");