добавление аргумента из метода map в метод foreach с использованием Java Stream - PullRequest
0 голосов
/ 21 ноября 2018

Я написал небольшой пример, чтобы объяснить мою проблему:

import java.util.Arrays;
import java.util.List;


public class Example {

     public static void main( String[] args )  {
         String [] array =  {"1 0101 5","1 0101 5"};
         Arrays.stream(array)
               .map(str->str.split(" "))//every String is mapped to an array of String
               .map(arr-> returnAListOf5Element( Integer.parseInt(arr[0]),arr[1],Integer.parseInt(arr[2])))
               .forEach(list-> tesMyList(list));//i want to send the Integer.parseInt(arr[2]) as a second argument
     }
    /**
     *
     * test if the list has size of 5
     */
    private static void testMyList(List<Integer> myList) {
         if (myList.size()==5)
             System.out.println("Ok");
    }

    /**
     *
     * return a list of 5 element
     * @return
     */
    private static List<Integer> returnAListOf5Element( int i, String s, int i1 ) {
         List list = Arrays.asList(1,2,3,4,5);
         return list;
    }
}

Итак, у меня есть несколько строк, таких как "1 0101 5", "1 0101 5" ....., я использую потоковую операцию, чтобысделайте несколько исчислений.

Проблема в том, что я хочу добавить аргумент arr [2], найденный в методе map, в метод testMyList , найденный в методе foreach.

метод testMyList должен выглядеть так:

 private static void testMyList(List<Integer> myList, int size) {
         if (myList.size()==size)
             System.out.println("Ok");
    }

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Создайте свой собственный класс для обслуживания ваших данных, а не используйте какой-нибудь универсальный, например, List.

class MyObject {
    public final int i;
    public final String string;
    public final int i1;
    public MyObject(int i, String string, int i1){
        this.i = i;
        this.string = string;
        this.i1 = i1;
    }
    public static MyObject parse(String line) {
        String[] split = line.split(" ");
        return new MyObject(Integer.parseInt(split[0], split[1], Integer.parseInt(split[2]);
    }
}

. Затем вы можете сделать

Files.lines(filename)
     .map(MyObject::parse)  // now you have a Stream of MyObjects
     .forEach(o -> verify(o));

, например,

void verify(MyObject object) {
    if (object.i1 < 5) {
        System.out.println("invalid");
    }
}
0 голосов
/ 21 ноября 2018

Я вижу три возможных решения:

  1. returnAListOf5Element возвращает arr[2] в списке.(скажем, по контакту, это последний элемент в возвращенном списке.) Это грязный подход.

  2. map возвращает Map.Entry<List<Integer>, Integer>, чтосостоит из результата вызова returnAListOf5Element(...) и arr[2]. Это более разумный способ.

Эти два идентификатора основаны на состоянии кэширования предыдущей операции, поэтому вы можете получить его при следующей.Это единственный способ получить результат, вычисленный в цепочке ранее.

Вы заменяете цепочку потоков простым циклом, в котором доступны все промежуточные вычисления.

Я считаю последний метод наиболее простым и эффективным с точки зрения производительности.Похоже, что здесь вы не получите никаких выгод от потоков.Я бы придерживался этого.

...