Je suis nouveau sur Java 8 et j'essaie de comprendre comment les flux et les filtres fonctionnent avec la liste. J'ai une liste de chaînes prédéfinies et une valeur de chaîne que je traite. Je souhaite ajouter la chaîne traitée à une nouvelle liste si la chaîne commence par l'une des chaînes de la liste prédéfinie. Si la chaîne ne correspond à aucune chaîne de la liste, enregistrez-la dans une autre liste.
Par exemple:
ipAddresseses.stream() .filter(ipAddress -> clientIpAddress.startsWith(ipAddress) .*if the clientIpAddress starts with any of the values in the list then add to internalIpAddresses List .*if clientIpAddress doesn't start with any values in list then add to externalIpAddresses List
Résultat :
internalIpAddresses: 10.11.12.13 externalIpAddresses : 5.6.7.8
Y a-t-il un moyen d'y parvenir de manière plus simple en utilisant le flux dans java 8?
Like:
List<String> internalIpAddresses= new ArrayList<>(); List<String> externalIpAddresses = new ArrayList<>(); List<String> ipAddresseses = new ArrayList<String>(); ipAddresses.add("10."); ipAddresses.add("132.174."); ipAddresses.add("192.168."); // filter internal ip addresses for(String ipAddress : ipAddresseses){ if("10.11.12.13".startsWith(ipAddress)) { internalIpAddresses.add("10.11.12.13"); } } // filter external ip addresses for(String ipAddress : ipAddresseses){ if(!"5.6.7.8".startsWith(ipAddress)) { externalIpAddresses .add("5.6.7.8"); } }
À la fin, je veux enregistrer le clientIpAddress
("10.11.12.13" ou "5.6. 7.8 "), pas les valeurs de la liste ipAddresses
(" 10. "ou" 192.168. ").
4 Réponses :
Vous pouvez essayer:
ipAddresseses.stream() .collect(Collectors.partitioningBy(ipAddress -> ipAddress.startsWith("10.11.12.13")));
Cela donnera une carte avec deux éléments, un avec un bon ipAddress et un avec un mauvais.
J'ai fait. Cela m'a renvoyé une liste avec la valeur "10." Je souhaite enregistrer clientIpAddress
dans la liste et non ipAddress
depuis ipAddresses
J'ai corrigé cette partie dans mon exemple de code sur ipAddress -> "10.11.12.13" .startsWith (ipAddress)
. La carte dans votre code peut-elle avoir "10.11.12.13" comme vrai parce qu'elle commence par l'une des valeurs de la liste ipAddresses? Ou ajoutez "5.6.7.8" comme faux car il ne commence par aucune valeur dans ipAddresses.
Je ne sais pas pourquoi les évaluateurs ont rejeté mes modifications dans votre commentaire, mais pourriez-vous s'il vous plaît me faire savoir si ma description a toujours un sens pour vous?
Vous pouvez le faire -
public void decideGoodOrBadAndAdd(String ipaddress){ if("10.11.12.13".startsWith(ipAddress)) { goodIpAddresses.add(ipAddress); } else if(!"5.6.7.8".startsWith(ipAddress)) { badIpAddresses.add(ipAddress); } }
Créez une méthode qui vérifiera si c'est une bonne ou une mauvaise adresse IP et l'ajouter dans la liste respective en conséquence-
ipAddresseses.stream().foreach( ipaddress -> decideGoodOrBadAndAdd(s);
Cela va ajouter 10.11.12.13 à badIpAddress lorsque la boucle forEach traite «192.168». ou "132.174." à partir de la ipAddressesList. C'est la raison pour laquelle, dans l'exemple, j'ai deux boucles séparées avec deux conditions.
Vous pouvez le faire en utilisant:
Map<Boolean, List<String>> ipMap = ipAddresses.stream() .collect(Collectors.partitioningBy(ipAddress -> ipAddress.startsWith("10."))); goodIpAddresses.addAll(ipMap.get(true)); badIpAddresses.addAll(ipMap.get(false));
Ici, la carte ipMap ne contiendra que deux clés selon le prédicat dans partitioningBy ( )
Pour récupérer les adresses IP qui doivent être ajoutées aux goodIpAddresses
, utilisez simplement la clé true et pour récupérer l'IP de badIpAddresses
utilisez la clé false.
C'est intéressant. Cependant, nulle part dans ipMap je ne trouve "10.11.12.13" qui est la bonne adresse IP que je veux ajouter à la liste goodIpAddresses. De plus, j'ai corrigé mon exemple de code avec ipAddress -> "10.11.12.13" .startsWith (ipAddress)
Simplement, votre code itératif utilisant des flux pourrait être représenté comme:
List<String> internalIpAddresses = Stream.of("10.11.12.13") // can add more addresses .filter(ip -> ipAddresses.stream().anyMatch(ip::startsWith)) .collect(Collectors.toList());
Une approche générale suggérée dans les commentaires pour résoudre ce problème pourrait être d'utiliser:
List<String> ipAddresses = Arrays.asList("10.", "132.174.", "192.168."); List<String> internalIpAddresses = ipAddresses.stream() .filter("10.11.12.13"::startsWith) .map(ipAddress -> "10.11.12.13") .collect(Collectors.toList()); List<String> externalIpAddresses = ipAddresses.stream() .filter(ipAddress -> !"5.6.7.8".startsWith(ipAddress)) // I doubt this should be '.filter("5.6.7.8"::startsWith)' .map(ipAddress -> "5.6.7.8") .collect(Collectors.toList());
C’est une façon étrange de traiter des éléments uniques. Lorsque l'on considère ces éléments comme un cas particulier d'un code à usage général, il serait plus logique d'utiliser, par exemple List
, qui permet d'insérer plus d'adresses à vérifier par l'opération.
@Holger true, mis à jour et appris pour une approche générique. Merci.