Сопоставить значение ключа с объектом в потоке Java 8 - PullRequest
0 голосов
/ 12 декабря 2018

Допустим, у меня есть этот код:

Map<String, String> map;
// later on
map.entrySet().stream().map(MyObject::new).collect(Collectors.toList());

И у меня есть MyObject Constructor, который принимает два аргумента типа String.Я хочу быть в состоянии сделать это, но я не могу.Я знаю, что могу сделать e -> new MyObject(e.getKey(), e.getValue()), но предпочитаю MyObject::new.

Аналогичный код работает для Set<String> и List<String> с одним конструктором аргумента MyObject класса.

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

Добавить конструктор Map.Entry

class MyObject {
        private final String k;
        private final String v;

        MyObject(String s1, String s2) {
            k = s1;
            v = s2;
        }

        MyObject(Map.Entry<String, String> e) {
            this(e.getKey(), e.getValue());
        }

        public String toString() {
            return "key: " + k + ' ' + "value: " + v;
        }
    }

Вы сможете позвонить

List<MyObject> myObjectList = map.entrySet().stream().map(MyObject::new).collect(Collectors.toList());
0 голосов
/ 12 декабря 2018
map.entrySet().stream().map(MyObject::new).collect(Collectors.toList()));

И у меня есть конструктор MyObject, который принимает два аргумента типа String.Я хочу быть в состоянии сделать это, но не могу.

В map.entrySet().stream().map(...) Java ожидает Function, сопоставляя одно значение другому.Одно значениеИз потока функция получает значение типа Map.Entry<String, String>, но ваш конструктор принимает два String аргумента.Java автоматически не расширяет Map.Entry<String, String> до пары String s для передачи вашему конструктору.Вы должны сделать это вручную.

0 голосов
/ 12 декабря 2018

Проблема с конструктором заключается в том, что он определяет два параметра, тогда как Function#apply, требуемый Stream#map, принимает только один.

Вы можете написатьстатический фабричный метод для MyObject

class MyObject {
    public static MyObject of(Map.Entry<String, String> e) {
        return new MyObject(e.getKey(), e.getValue());
    }
}

и ссылаться на него как

map(MyObject::of)

Прежде чем сделать это, спросите себя, есть ли одна симпатичная линия в простой обработкецепочка где-то достойна нового конструктора или служебного метода.

0 голосов
/ 12 декабря 2018

используйте лямбду:

map.entrySet()
   .stream()
   .map(e -> new MyObject(e.getKey(), e.getValue()))
   .collect(Collectors.toList());

, иначе единственный способ использовать ссылку на метод - создать функцию как таковую:

private static MyObject apply(Map.Entry<String, String> e) {
      return new MyObject(e.getKey(), e.getValue());
}

, затем сделать что-то вроде:

map.entrySet()
   .stream()
   .map(Main::apply)
   .collect(Collectors.toList());

Где Main - класс, содержащий метод apply.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...