2016-10-12 1 views
5

Quelqu'un peut-il m'aider à convertir le code suivant pour utiliser des références de méthode? Je suis en train d'envelopper ma tête autour de cette nouvelle syntaxe, mais je me perds rapidement quand il est plus complexe qu'une seule variable se mappé à un seul appel de méthode:Convertir lambdas en références de méthode

getWorkspaces().stream().forEach((ws) -> { 
      DataStoreInfo defaultDataStore = getDefaultDataStore(ws); 
      if (defaultDataStore != null) { 
       other.setDefaultDataStore(ws, defaultDataStore); 
      } 
     }); 

J'ai commencé avec cela, mais il n » travail t :)

getWorkspaces().stream() 
       .map(this::getDefaultDataStore) 
       .filter(Objects::nonNull) 
       .map(other::setDefaultDataStore); 

Edit: Par « ça ne marche pas », je veux dire l'IDE se plaint sur la dernière ligne de « setDefaultDataStore » qu'il ne peut pas résoudre la méthode. J'aimerais pouvoir commencer par quelque chose qui fonctionne, mais je ne sais pas comment y arriver. Je suis très confus sur la façon d'utiliser les références de méthode pour appeler une méthode qui prend 2 paramètres et comment cela est mappé. J'ai converti un code qui ressemble à ceci:

getMaps().stream().forEach((m) -> { 
      other.add(m); 
     }); 

à ceci:

getMaps().forEach(other::add); 

Mais je suis perdu quand il est plus complexe. J'espérais qu'il y avait une solution évidente sur la façon d'écrire le même code avec des références de méthode.

+3

Que voulez-vous dire par "ça ne marche pas"? Veuillez être plus précis, et idéalement fournir un [mcve]. –

+2

@GhostCat: Je ne l'ai pas, mais "ça ne marche pas" sans plus de détails en fait une question loin d'être idéale. –

+2

Avant d'essayer "d'utiliser une référence de méthode", vous devez écrire quelque chose qui fonctionne sans ...Le deuxième extrait ne fonctionnerait pas même avec l'expression lambda et n'est pas lié à l'utilisation de références de méthode. Tout d'abord, vous avez besoin de deux paramètres dans 'setDefaultDataStore'. Donc vous devez les stocker. – Tunaki

Répondre

1

Vous pouvez convertir votre code dans la version lambda comme ceci mais ce n'est pas propre comme prévu.

words.stream().map(ws -> new SimpleImmutableEntry<>(ws, getDefaultDataStore(ws))) 
       .filter(e -> e.getValue() != null) 
       .forEach(e -> setDefaultDataStore(e.getKey(), e.getValue())); 

Note: e est le abréviation pour l'entrée.

1

Vous pouvez lire beaucoup d'informations utiles ici sur la méthode référence https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

Si votre lambda ne fait que les appels méthode existait, vous pouvez le remplacer par référence de la méthode. Donc, si vous êtes à l'aise avec lambdas, vous pourrez facilement faire face aux références de méthode.

Il y a 4 types d'entre eux

  1. référence à une méthode statique - ContainingClass :: staticMethodName
  2. référence à une méthode d'instance d'un objet particulier - containingObject :: instanceMethodName
  3. Référence à un instance méthode d'un objet arbitraire d'un type particulier - ContainingType :: nomMéthode
  4. Référence à une construction tor - ClassName :: new

Retour à votre question: .map (other :: setDefaultDataStore);

Vous ne devez pas utiliser la fonction de carte pour effectuer des opérations secondaires sur des membres de flux, mais pour transformer un flux dans un autre. Utilisateur foreach à la place

getWorkspaces().stream() 
       .map(this::getDefaultDataStore) 
       .filter(Objects::nonNull) 
       .foreach(other::setDefaultDataStore);