2017-04-05 31 views
-1

我有選擇性地將數據添加到地圖類似下面的代碼,從列表中刪除元素根據病情

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)地圖是否有多個記錄具有相同的名字;如果記錄的姓名爲空,那麼它應該將此記錄添加到地圖中。 2)如果地圖只有一個人的名字記錄;如果該記錄的姓氏爲空,則它有資格添加到地圖中。

所以輸出爲我的目前的解決方案是,

約翰尼 ·德普

詹妮弗 空

安吉麗娜 大蒜

凡爲我所需的輸出應該是,

約翰尼 ·德普

詹妮弗 空

安吉麗娜 大蒜

安吉麗娜 朱莉

注意:我正在使用的Java 7的(不,JAVA 8是不是一種選擇)

+0

我想你的意思是,如果有多個記錄與samme的名字和一個有空的姓氏,那麼它應該*不*被添加? –

+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

是的,我早些時候嘗試了這種方法,但發現設計不太優雅,因爲它使用了兩個數據結構,然後單獨循環它們。雖然我想不出任何其他方法,但感謝解決方案!投票! – Raskill

+0

@PewDiePie我用'Map >'添加了下面提到的方法的實現。感謝upvote,祝你好運! –

1

HashMap中不允許重複鍵(名字),所以你不能看到安吉麗娜·朱莉在你的地圖。 從Java HashMap的文檔。

公共五世說(K鍵, PV值) 將指定值與此映射中指定的鍵。如果地圖先前包含密鑰的映射,則舊值將被替換。

因此,我向你推薦兩種方法,以解決您的問題:

  1. 做一個Map<String,List<Person>>所以這裏的關鍵是firstName和列表是每個人必須你的要求。

  2. 使用支持multikey的實現,如Apache Commons Collections的Multimap或Guava。

+0

我認爲第一種方法會再次需要很多條件,特別是在檢查密鑰是否已經不在地圖中時,然後創建一個新的數組列表,然後將其添加到與密鑰關聯的地圖中。 雖然,我正在考慮第二種方法,但是我之前並沒有使用過多個地圖,如果你可以對它進行一些指示(對我真的有幫助)。此外,如果你可以建議一種替代方法,而不是使用地圖 – Raskill

0

我想我會在兩次通過。

在第一遍中,只能將臨時映射中非空的姓氏放入記錄中。不要介意重複的名字現在會丟失。

在第二遍之前,創建一個結果集合,集合或列表。地圖不會。在第二遍中,對於姓氏爲空的每條記錄,可以檢查地圖中是否存在具有相同名字和非空姓氏的記錄。現在你知道哪些記錄應該進入你的結果。

而不是臨時地圖一組名字是真的夠了。