2017-06-13 103 views
4

請人幫我在Java8 streamAPI爲此,Java8流循環迭代

for(ContactDto contact : contactList){ 
    for(ContactContactTypeDto contactType : contact.getContactTypes()){ 
     if(PRIMARY_CONTACT.equals(contactType.getIdContactTypeCode())){ 
      StringBuilder contactNameSB = new StringBuilder(contact.getFirstName()); 
      contactNameSB.append(" "); 
      if(null!=contact.getMiddleName() && !contact.getMiddleName().isEmpty()){ 
       contactNameSB.append(contact.getMiddleName()); 
       contactNameSB.append(" "); 
      } 
      contactNameSB.append(contact.getLastName()); 

      contactName = contactNameSB.toString(); 
      contactEmail = contact.getEmailAddress(); 
     } 
    } 
} 

我試過,但我只能達到高達

contactList.stream() 
    .filter(contact -> contact.getContactTypes() 
     .stream() 
     .anyMatch(contactType -> PRIMARY_CONTACT.equals(contactType.getIdContactTypeCode()))); 
+0

您的循環不太合理,您迭代了聯繫人,但'contactEmail'和'contactName'將始終是循環中最後一個'ContactDto',因爲它們被覆蓋。你錯過了一個「休息」嗎? – Rogue

+0

你能解釋一下應該是什麼結果。應該使用contactNameSB執行什麼操作。我不能看到這個代碼的任何用法。 –

回答

2

它可能是有意義的使用Stream管道獲取您想要提取的細節的單個ContactDto

ContactDto contact = 
    contactList.stream() 
       .filter(c -> c.getContactTypes() 
          .stream() 
          .anyMatch(t->PRIMARY_CONTACT.equals(t.getIdContactTypeCode()))) 
       .findFirst() 
       .orElse(null); 

然後使用該實例所需的值分配給你的兩個變量:

if (contact != null) { 
    StringBuilder contactNameSB = new StringBuilder(contact.getFirstName()); 
    contactNameSB.append(" "); 
    if(null!=contact.getMiddleName() && !contact.getMiddleName().isEmpty()) { 
     contactNameSB.append(contact.getMiddleName()); 
     contactNameSB.append(" "); 
    } 
    contactName = contactNameSB.toString(); 
    contactEmail = contact.getEmailAddress(); 
} 

注:

這將根據找到的第一個匹配ContactDto實例分配值。

+0

很酷..這工作很好.. –

3

當使用java 8流的代碼變得複雜時,創建一些其他類型和方法是有益的。例如。

的方法來創建一個完整的名字來自它的部分(你不需要StringBuilder編譯器將使用一個在這種情況下):

String createFullName(ContactDto contact) { 
    String contactName = contact.getFirstName() + " "; 
    if (null != contact.getMiddleName() && !contact.getMiddleName().isEmpty()) { 
     contactName += contact.getMiddleName() + " "; 
    } 
    return contactName + contact.getLastName(); 
} 

類來保存結果,基本上是對名稱的和電子郵件(添加構造,吸氣等):

class Contact { 
    private String name; 
    private String email; 
} 

而且現在的代碼變得簡單多了:

Optional<Contact> contact = contactList.stream() 
     .filter(c -> c.getContactTypes() 
       .stream() 
       .map(ContactContactTypeDto::getIdContactTypeCode) 
       .anyMatch(PRIMARY_CONTACT::equals)) 
     .findFirst() 
     .map(c -> new Contact(createFullName(c), c.getEmailAddress())); 

完成之後的額外代碼是findFirst,它將返回描述此流的第一個元素的Optional,如果流爲空,則返回一個空的可選項。

最後的map將應用於生成的如果它不爲空以創建Contact或返回空Optional<Contact>

+0

Thanx ..這工作正常,但我不想創建一個新的類 –

+0

在這種情況下,你可以(ab)使用[SimpleEntry](https://docs.oracle.com /javase/8/docs/api/java/util/AbstractMap.SimpleEntry.html)或各種庫中的「Pair」實現之一。 –

0
List<ContactDto> contactListWithPrimaryContact = contactList.stream() 
       .filter(contact -> contact.getContactTypeDto().parallelStream() 
         .anyMatch(x -> x.getIdContactTypeCode().equals(PRIMARY_CONTACT))) 
       .collect(Collectors.toList()); 

在獲得與primaryContact類型的所有聯繫後,請執行進一步的操作。

第一次接觸類型爲PRIMARY_CONTACT並將值賦給全局變量似乎沒用。

因爲按照上面的解決方案,第二次聯繫列表中contactType爲PRIMARY,我們忽略它。