arraylist contains()不使用类的equals()方法



我知道这个问题有很多答案。但是我还没有找到解决方案。

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()方法。

最新更新