2017-06-13 65 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,我们忽略它。