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

时间:2014-02-06 20:09:22

标签: java arraylist

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

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;
    }
}

当我在contains()上使用ArrayList时,它没有使用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()没有调用equals()类的IpAdressRange方法。

1 个答案:

答案 0 :(得分:4)

问题是您equals()的实施与InetAddress的实施不一致。 equals()方法应该是对称的。

查看合约here

  

equals方法在非null对象引用上实现等价关系:

     
      
  • 它是自反的:对于任何非空参考值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一样实现它,但不能反过来,因为您无法从{{1}编辑equals()方法}。