我有一个代码可以选择性地将数据添加到地图中,如下所示,
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Johnny", "Depp", 18),
new Person("Jennifer", null, 30),
new Person("Angelina", null, 23),
new Person("Angelina", "Garlic", 38),
new Person("Angelina", "Jolie", 40),
);
Map<String, Person> map = new HashMap<>();
for (Person person:
people) {
Person temp = map.get(person.getFirstName());
if(temp == null || temp.getLastName() == null)
map.put(person.getFirstName(), person);
}
for (Map.Entry mapper:
map.entrySet()) {
Person temp = (Person) mapper.getValue();
System.out.println(temp.getFirstName());
System.out.println(temp.getLastName());
System.out.println();
}
}
Person.java包含以下内容:
public class Person {
String firstName;
String lastName;
int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
现在,我需要检查以下条件, 1)是地图有多个具有相同名字的记录;如果记录的姓氏为null,则应将此记录添加到地图中。 2)如果地图只有一个人的名字的记录;如果该记录的姓氏为null,则它有资格添加到地图中。
因此我获得的当前解决方案的输出是,
约翰尼 德普
珍 空
安吉丽娜 大蒜
我所需的输出应该在哪里,
约翰尼 德普
珍 空
安吉丽娜 大蒜
安吉丽娜 朱莉
注意:我正在使用Java 7(不,java 8不是一个选项)
答案 0 :(得分:2)
这是因为,在地图中,密钥必须是唯一的,所以当你第二次检查安吉丽娜并且匹配因为姓氏是null
并且你放入地图时你会覆盖原来的安吉丽娜。 Maps必须有唯一的密钥,
公共接口地图 将键映射到值的对象。地图不能包含重复的键;每个键最多可以映射一个值。
<强> 1。使用补充列表来维护将覆盖当前键的对象
List<Person> supplementaryList = new ArrayList<Person>();
Map<String, Person> map = new HashMap<String, Person>();
for (Person person : people) {
Person temp = map.get(person.getFirstName());
if (temp != null) {
supplementaryList.add(person);
if (temp.getLastName() == null)
map.remove(temp.getFirstName());
} else {
map.put(person.getFirstName(), person);
}
}
for (Map.Entry mapper : map.entrySet()) {
Person temp = (Person) mapper.getValue();
System.out.println(temp.getFirstName());
System.out.println(temp.getLastName());
System.out.println();
}
for (Person p : supplementaryList) {
System.out.println(p.getFirstName() + p.getLastName());
}
<强> 2。使用Map<String,List<Person>>
Map<String, List<Person>> namesMap = new HashMap<String, List<Person>>();
for (Person p : people) {
List<Person> res = namesMap.get(p.getFirstName());
// if there is not valid list of names for key add new person
if (res == null) {
List<Person> newListOfPeople = new ArrayList<Person>();
newListOfPeople.add(p);
namesMap.put(p.getFirstName(), newListOfPeople);
} else {
if (p.getLastName() != null) {
res.add(p);
namesMap.put(p.getFirstName(), res);
Iterator<Person> iter = res.iterator();
// remove null from list if it exists
while (iter.hasNext()) {
Person person = iter.next();
if (person.getLastName() == null)
iter.remove();
}
}
}
}
for (Map.Entry<String, List<Person>> kv : namesMap.entrySet()) {
if (kv.getValue() != null) {
for (Person p : kv.getValue())
System.out.println(p.getFirstName() + " " + p.getLastName());
}
}
<强>输出强>
Johnny Depp
Jennifer null
Angelina Garlic
Angelina Jolie
答案 1 :(得分:1)
HashMap不允许重复键(firstName),因此您无法在地图中看到Angelina Jolie。 来自java HashMap的文档。
公共V放(K键, V值) 将指定的值与此映射中的指定键相关联。如果地图以前包含该键的映射,则替换旧值。
因此,为了解决您的问题,我建议您采用两种方法:
创建一个Map<String,List<Person>>
所以这里的密钥是firstName,List是每个必须满足您要求的人。
使用支持多键的实现,例如Apache Commons Collections的Multimap,或者来自Guava。
答案 2 :(得分:0)
我想我会两次通过。
在第一遍中,仅将具有非空姓的记录放入临时地图中。不要紧,重复的名字暂时会丢失。
在第二次传递之前,创建一个结果集合,可以是set或list。地图不会这样做。在第二遍中,对于具有null lastname的每个记录,您可以在映射中检查是否存在具有相同名字和非null姓氏的任何记录。现在你知道哪些记录应该进入你的结果。
而不是临时地图,一组名字就足够了。