考虑员工类 -
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
创建了2个员工对象 -
These credentials do not match our records.
将它们添加到hashset后,大小将为2。 HashSet在内部使用hashmap来保持唯一性 -
public class Employer implements Serializable{
private Long id;
private String name;
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj instanceof Employer) {
Employer employer = (Employer) obj;
if (this.id == employer.id) {
return true;
}
}
return false;
}
//Idea from effective Java : Item 9
@Override
public int hashCode() {
int result = 17;
result = 31 * result + id.hashCode();
//result = 31 * result + name.hashCode();
return result;
}
}
现在,如果我将第二个员工的id设置为与第一个员工的id相同,即 -
Employer employer1 = new Employer();
employer1.setId(10L);
Employer employer2 = new Employer();
employer2.setId(11L);
大小仍然是2。 为什么不是1? in-variants是否会被破坏?
答案 0 :(得分:8)
尺寸仍然是2.为什么不是1? in-variants是否会被破坏?
如果您修改hashCode
中已有的实例用于计算equals
和HashSet
的任何属性,则HashSet
实施不知道该更改。
因此它会保留两个实例,即使它们现在彼此相等。
您不应对作为成员或HashSet
s(或HashMap
s中的键)的实例进行此类更新。如果您必须进行此类更改,请在变更之前从Set
中删除该实例,然后再重新添加。
答案 1 :(得分:8)
所有基于散列的容器(包括HashSet<T>
)都对其键的哈希码做出了非常重要的假设:它们假设哈希代码在对象位于容器内时永远不会改变。
您的代码违反了此假设,因为它仍然在哈希集中时修改实例。 HashSet<T>
没有实际的方法来应对此更改,因此您必须选择以下两种方法之一来处理此问题:
第二种方法经常成为维护问题的根源。当您需要在基于散列的容器中保留可变数据时,一种好方法是在计算哈希代码和相等性检查时仅使用final
个字段。在您的示例中,这意味着制作id
字段final
,并从类中删除setId
方法。