2016-11-25 5 views
-1

У меня есть список всех списков (извинения за отвратительный код) Как скрыть это от лямбда?Как мне преобразовать это в lambda

List<EmailAddressInformationDataType> emailInfoDataList = workerType.getWorkerData().getPersonalData().getContactData().getEmailAddressDatas(); 

for(EmailAddressInformationDataType infoData : emailInfoDataList) 
{ 
    List<CommunicationMethodUsageInformationDataType> usageInfoList = infoData.getUsageDatas(); 
    for(CommunicationMethodUsageInformationDataType methodUsage : usageInfoList) 
    { 
     if(methodUsage.isPublic()) 
     { 
      List<CommunicationUsageTypeDataType> usageTypes = methodUsage.getTypeDatas(); 

      for(CommunicationUsageTypeDataType usageType : usageTypes) 
      { 
       if(usageType.isPrimary()) 
       { 
        CommunicationUsageTypeObjectType typeRefs = usageType.getTypeReference(); 
        typeRefs.getIDS().stream() 
              .filter(id -> id.getType().equals(WorkdayDataType.Communication_Usage_Type_ID) 
                  && id.getValue().equalsIgnoreCase("WORK")); 
          email = infoData.getEmailAddress(); 
          break; 
         } 
        } 
       } 

      } 
     } 

Я попытался следующий, но до сих пор не удалось получить по электронной почте:

emailInfoDataList.stream() 
         .peek(s -> s.getEmailAddress()) 
         .flatMap(s -> s.getUsageDatas().stream()) 
         .filter(s -> s.isPublic()) 
         .flatMap(s -> s.getTypeDatas().stream()) 
         .filter(s -> s.isPrimary()) 
         .map(s -> s.getTypeReference()) 
         .flatMap(s -> s.getIDS().stream()) 
         .filter(s-> s.getType().equals(WorkdayDataType.Communication_Usage_Type_ID) 
            && s.getValue().equalsIgnoreCase("WORK")) 
         ; 
+0

1) не используйте 'peek' для получения значения, но используйте оператор терминала, например. 'findFirst(). orElse (...)' 2) не flatMap все, поскольку вы теряете информацию, так как ваша область становится все меньше и меньше, вместо этого поток исходного списка usesDatas и если вам нужен фильтр который нуждается в внутреннем цикле, делегировать другому методу, который будет настраивать собственный поток и выполнить конкретную проверку. –

+0

Спасибо за подсказку. Но не могли бы вы показать мне пример о том, как это сделать? – user293655

ответ

1

Резюме

Пар вещей:

  • использовать терминальный оператор вместо от peek, чтобы найти любой адрес электронной почты, мы будем использовать findAny
  • сохранить поток на EmailAddressInformationDataType уровне, чтобы получить Адресные электронную почту из нее, если есть какой-либо найдены
  • делегат осмотр, чтобы увидеть, если пользователь имеет адрес работы в соответствующих классы, чтобы получить надлежащую герметизацию и чистый код

Ваш getEmail() метод

Начало в верхней части, мы хотим, чтобы метод, который возвращает адрес электронной почты, если работа адрес электронной почты найден, если мы не просто возвращать пустую строку:

private String getEmail() { 
     return workerType.getWorkerData().getPersonalData().getContactData().getEmailAddressDatas().stream() 
         .filter(EmailAddressInformationDataType::hasWorkEmail) 
         .findAny() 
         .map(EmailAddressInformationDataType::getEmailAddress) 
         .orElse(""); 
    } 

Замечание, что findAny возвращает Optional. Если вы не знаете, как его использовать, сделайте некоторое исследование, оно используется здесь как чистое решение для получения адреса электронной почты от найденного EmailAddressInformationDataType или, если его не найти, возвращается пустая строка.

Еще сделать:

  • очистить длинную геттер цепь, извлекая его к способу либо в этом классе или в WorkerType класса
  • возможно поставить hasWorkEmail и getEmailAddress в классе, как статический метод, получающий EmailAddressInformationDataType. Если вы назовете класс EmailAddress, вы можете написать EmailAddress:hasWorkMail, который короче и легче читать.

hasWorkEmail() метод на EmailAddressInformationDataType

EmailAddressInformationDataType появился новый метод, называемый hasWorkEmail():

public boolean hasWorkEmail() { 
    return getUsageDatas().stream() 
          .filter(CommunicationMethodUsageInformationDataType::isPublic) 
          .anyMatch(CommunicationMethodUsageInformationDataType::hasWorkEmail); 
} 

Если вы не можете настроить -DataType классы, потому что они генерируются, смотрите на предыдущие замечания: переместите их в статический класс EmailAddress с помощью метода, который принимает EmailAddressInformationDataType. Обратите внимание, что используемый здесь метод isPublic является только существующим. Не стесняйтесь снова перемещать isPublic и hasWorkEmail в статический метод с более коротким именем, например CommunicationMethodUsage, оставляя все шаблонные суффиксы.

hasWorkEmail() метод на CommunicationMethodUsageInformationDataType

Та же история и здесь, простой поток с отображениями и фильтрами. Мы используем anyMatch, чтобы увидеть, если какой-либо адрес электронной почты работа адрес электронной почты:

public boolean hasWorkEmail() { 

    return getTypeDatas().stream() 
        .filter(CommunicationUsageTypeDataType::isPrimary) 
        .map(CommunicationUsageTypeDataType::getTypeReference) 
        .map(CommunicationUsageTypeObjectType::getIDS) 
        .flatMap(List::stream) 
        .filter(id -> id.getType().equals(WorkdayDataType.Communication_Usage_Type_ID)) 
        .anyMatch(id -> "WORK".equalsIgnoreCase(id.getValue())); 

} 

Этот код компилируется и работает; он должен дать вам определенное начало о том, как переписать свой код и решить остальную часть кода таким же образом.

Смежные вопросы