9
votes

Java 8 - Filtrer une chaîne-X à partir d'une liste à l'aide de startsWith et enregistrer la chaîne-X dans une liste

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. ").


0 commentaires

4 Réponses :


6
votes

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.


3 commentaires

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?



5
votes

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);


1 commentaires

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.



2
votes

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.


1 commentaires

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)



5
votes

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());


2 commentaires

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 internalIpAddresses = Stream.of ("10.11.12.13"). filter (ip -> ipAddresses.stream (). anyMatch (prefix -> ip.startsWith (prefix)). collect (toList ()) ; , 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.