我知道这个问题有很多答案。但是我还没有找到解决方案。
class IpAddressRange
{
InetAddress start;
InetAddress end;
public IpAddressRange(String start, String end) throws Exception
{
this.start = InetAddress.getByName(start);
this.end = InetAddress.getByName(end);
}
@Override
public boolean equals(Object input)
{
System.out.println("Inside equals");
long lv = IpAddressRange.ipToLong(start);
long hv = IpAddressRange.ipToLong(end);
if(input != null && input instanceof InetAddress)
{
long iv = IpAddressRange.ipToLong((InetAddress)input);
if( iv >= lv && iv <= hv)
return true;
}
return false;
}
@Override
public String toString()
{
return start.getHostAddress() + "-" + end.getHostAddress();
}
public static long ipToLong(InetAddress ip) {
byte[] octets = ip.getAddress();
long result = 0;
for (byte octet : octets) {
result <<= 8;
result |= octet & 0xff;
}
return result;
}
}
当我在ArrayList
上使用contains()
时,它不使用equals()
方法。
ArrayList<IpAddressRange> allocatedList = new ArrayList<IpAddressRange>();
allocatedList.add(new IpAddressRange("10.10.10.10","10.10.10.12"));
以下是调用 contains()
的代码:
InetAddress inetAddress1 = InetAddress.getByName("10.10.10.11");
allocatedList.contains(inetAddress1);
但是此contains()
没有调用IpAdressRange
类的equals()
方法。
问题是您对equals()
的实现不同意InetAddress
的实现。equals()
方法应为对称。
在这里查看合同:
等于非记录对象引用上的等效关系:
- 它是反身的:对于任何非零参考值x,
x.equals(x)
应该返回真实。- 它是对称的:对于任何非零用参考值 x和y,
x.equals(y)
应在且仅当y.equals(x)
时返回true 返回true。- 它是传递的:对于任何非零用参考值x, y和z,如果x。equals(y)返回true,并且
y.equals(z)
返回true, 然后x. equals(z)应返回true。- 这是一致的:对于任何 非零参考值x和y,
x.equals(y)
的多个调用 始终返回true或始终返回false,没有提供 在对象上的比较中使用的信息已修改。为了 任何非零参考值x,x.equals(null)
均应返回false。
关键是您可能能够像anIpAddressRange.equals(anInetAddress)
返回true
一样实现它,而不是相反,因为您无法从InetAddress
编辑equals()
方法。