Java 8 - отфильтруйте строку-X из списка, используя StartWith и сохраните строку-X в список - PullRequest
0 голосов
/ 08 января 2019

Я новичок в Java 8 и пытаюсь понять, как потоки и фильтры работают со списком. У меня есть список предопределенных строк, и у меня есть строковое значение, которое я обрабатываю. Я хочу добавить обработанную строку в новый список, если строка начинается с какой-либо из строк в предопределенном списке. Если строка не соответствует ни одной строке из списка, сохраните ее в другом списке.

Например:

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

Результат:

internalIpAddresses: 10.11.12.13
externalIpAddresses : 5.6.7.8 

Есть ли способ, которым это может быть достигнуто более простым способом с помощью потока в Java 8?

Как:

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

В конце я хочу сохранить clientIpAddress ("10.11.12.13" или "5.6.7.8"), а не значения из списка ipAddresses ("10." или "192.168.").

Ответы [ 4 ]

0 голосов
/ 09 января 2019

Проще говоря, ваш итерационный код с использованием потоков может быть представлен как:

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

Общий подход, предложенный в комментариях для решения этой проблемы, может быть следующим:

List<String> internalIpAddresses = Stream.of("10.11.12.13") // can add more addresses
        .filter(ip -> ipAddresses.stream().anyMatch(ip::startsWith))
        .collect(Collectors.toList());
0 голосов
/ 08 января 2019

Вы можете сделать это -

  ipAddresseses.stream().foreach( ipaddress 
 -> decideGoodOrBadAndAdd(s);

Создайте один метод, который будет проверять, хороший ли он или плохой IP-адрес, и добавьте его в соответствующий список -

  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);
   }
}
0 голосов
/ 08 января 2019

Вы можете сделать это, используя:

Map<Boolean, List<String>> ipMap = ipAddresses.stream()
               .collect(Collectors.partitioningBy(ipAddress -> ipAddress.startsWith("10.")));

goodIpAddresses.addAll(ipMap.get(true));
badIpAddresses.addAll(ipMap.get(false));

Здесь карта ipMap будет содержать только два ключа в зависимости от предиката в partitioningBy()

Чтобы получить IP-адреса, необходимые для добавления к goodIpAddresses, просто используйте ключ true , а для получения IP-адресов для badIpAddresses используйте ключ false .

0 голосов
/ 08 января 2019

Вы можете попробовать:

ipAddresseses.stream()
 .collect(Collectors.partitioningBy(ipAddress -> ipAddress.startsWith("10.11.12.13")));

Это даст карту с двумя элементами, один с хорошим ipAddress и один с плохим.

...