簡體   English   中英

根據條件從列表中刪除元素

[英]Removing elements from list based on condition

我有一個代碼,可以有選擇地向地圖添加數據,如下所示:

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)如果地圖上只有一個人的名字記錄; 並且該記錄的姓氏為空,則符合添加到地圖的條件。

所以我當前解決方案的輸出是

約翰尼·德普

珍妮弗null

安吉麗娜·大蒜(Angelina Garlic)

我所需的輸出應該在哪里

約翰尼·德普

珍妮弗null

安吉麗娜·大蒜(Angelina Garlic)

安吉麗娜·朱莉

注意:我正在使用Java 7(不,不能使用Java 8)

這是因為,在地圖中,鍵必須是唯一的,因此當您第二次檢查安吉麗娜時,它是匹配的,因為姓為null並且您放入地圖中時,您將覆蓋原始的安吉麗娜。 地圖必須具有唯一鍵,

公共接口Map一個將鍵映射到值的對象。 映射不能包含重復的鍵; 每個鍵最多可以映射到一個值。

我發現了兩種不同的解決方法

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

HashMap不允許重復的鍵(名字),因此您在地圖中看不到Angelina Jolie。 來自Java HashMap的文檔。

public V put(K key,V value)在地圖中將指定值與指定鍵關聯。 如果該映射先前包含該鍵的映射,則將替換舊值。

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

  1. 制作一個Map<String,List<Person>>所以這里的鍵是firstName,而List是必須滿足您要求的每個人。

  2. 使用支持多鍵的實現,例如Apache Commons Collections的Multimap或來自Guava的實現。

我想我會分兩次通過。

在第一遍中,僅將姓氏為非空的記錄放入臨時映射中。 沒關系,重復的名字暫時會丟失。

在第二遍之前,創建結果集合(集合或列表)。 地圖不會。 在第二遍中,對於姓氏為空的每個記錄,您可以在映射中檢查是否存在具有相同名字和非空姓氏的記錄。 現在,您知道哪些記錄應該包含在您的結果中。

代替臨時映射,一組名字確實足夠了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM