我在Java项目中遇到了一个问题。产生错误的代码如下:
HashMap<String, LinkedList<? extends User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<Administrator>(),
"Employee", new LinkedList<Employee>(),
"Customer", new LinkedList<Customer>()));
for (String userName : userNameList)
{
userPropertyValue = usersProperties.getProperty(userName).split(",");
String password = userPropertyValue[0].replaceAll("\s", "");
String role = userPropertyValue[1].replaceAll("\s", "");
if (role.equals("Administrator"))
{
signedUpUsers.get("Administrator").add(new Administrator(userName, password));
}
else if (role.equals("Customer"))
{
signedUpUsers.get("Customer").add(new Customer(userName, password));
}
else
{
signedUpUsers.get("Employee").add(new Employee(userName, password));
}
}
当我尝试在hashmap的每个列表中添加新元素时,它给了我一个错误,当我创建实例时,intellij告诉我:
所需类型:捕获?扩展用户
提供:客户(或雇员或管理员)
但是为什么,如果客户员工,管理员和User?
我应该改变什么?我的意图是拥有一个包含所有注册用户的HashMap(我将它们保存在.properties文件中,该文件被更正为红色,因为我看到了这一点),其中键是用户的角色(管理员、雇员和客户),每个键的值是具有该角色的每个用户的LinkedList。我还尝试使用super代替扩展,但是在这种情况下,我解决了这个错误,但是在使用Map.of()创建hashmap时出现了一个新的错误(因为Administrator, Customer和Employee不是User的超类)。如果我用3个角色对象直接声明了3个不同的列表,那么代码就可以工作,但是我想要hashmap,因为我想返回整个注册用户除以他们的角色。
谢谢大家,我希望我解释得很清楚。
编译器错误的原因已经涵盖在@Thomas的评论中:对于编译器,signedUpUsers.get("Administrator")
是LinkedList<? extends User>
,不知道在"Administrator"
键下,您存储了LinkedList<Administrator>
(而不是例如LinkedList<Employee>
),因此编译器不允许添加Administrator
。
您的signedUpUsers
变量显示了一些明显的泛型过度工程。你声明
HashMap<String, LinkedList<? extends User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<Administrator>(),
"Employee", new LinkedList<Employee>(),
"Customer", new LinkedList<Customer>()));
我建议改成
HashMap<String, LinkedList<User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<User>(),
"Employee", new LinkedList<User>(),
"Customer", new LinkedList<User>()));
你可能会问:"但是现在我没有类型安全,我只能在"Administrator"
键下存储Administrator
实例。"但是这种类型安全在第一个版本中也是不可能的(在运行时,LinkedList<Administrator>
只是一个LinkedList,并且会很高兴地接受任何Object
,而在编译时LinkedList<? extends User>
将不允许添加任何内容)。
如果你想要列表的类型安全,扔掉Map
方法,创建一个类UserList
:
public class UserList {
private List<Administrator> administrators;
private List<Employee> employees;
private List<Customer> customers;
// add constructor, getters, adders etc. here
}
这将很容易地提供所需的类型安全。