Невозможно использовать ToIntFunction <T>вместо Functionв Collectors.toMap - PullRequest
0 голосов
/ 10 ноября 2019

Я пробую различные варианты в потоках Java 8. Теперь преобразование списка в карту. Ниже приведен пример кода.

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

public class MainTest {

  public static void main(String[] args) {

    MainTest obj = new MainTest();
    obj.testFunc();
  }

  private void testFunc() {

    List<Hosting> list = new ArrayList<>();
    list.add(new Hosting(1, "liquidweb.com", 80000));
    list.add(new Hosting(2, "linode.com", 90000));
    list.add(new Hosting(3, "digitalocean.com", 120000));
    list.add(new Hosting(4, "aws.amazon.com", 200000));
    list.add(new Hosting(5, "mkyong.com", 1));

    // No issues With lambda expression
    Map<Integer, String> resultWithLambda =
        list.stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getName()));

    // No issues With method reference
    Map<Integer, String> resultWithMethodRef =
        list.stream().collect(Collectors.toMap(Hosting::getId, Hosting::getName));

    // No Issues With java.util.function.Function
    Map<Integer, String> resultWithFuncMapper =
        list.stream().collect(Collectors.toMap(sampleMapper, Hosting::getName));

    // Compile time error with java.util.function.ToIntFunction

    // The method toMap(Function<? super T,? extends K>, Function<? super T,? extends U>) in the
    // type Collectors is not applicable for the arguments (ToIntFunction<MainTest.Hosting>,
    // Hosting::getName)
    Map<Integer, String> resultWithToIntFuncMapper =
        list.stream().collect(Collectors.toMap(sampleToIntMapper, Hosting::getName));

  }

  private ToIntFunction<Hosting> sampleToIntMapper = (Hosting input) -> {
    return input.getId();
  };

  private Function<Hosting, Integer> sampleMapper = (Hosting input) -> {
    return input.getId();
  };

  @Getter
  @Setter
  @AllArgsConstructor
  class Hosting {
    private int Id;
    private String name;
    private long websites;

  }

}

Я пытался изменить Function на ToIntFunction на основе правила SonarQube

«Функциональные интерфейсы должны быть как можно более специализированными - squid: S4276»

Но я получаю ошибку компиляции, когда меняю это значение на «ToIntFunction». Пожалуйста, помогите решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 10 ноября 2019

Collectors.toMap принимает Function в качестве аргумента, но вы пытаетесь передать ToIntFunction , которая не имеет отношения к Функция

public static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper,
                                                Function<? super T,? extends U> valueMapper)

Так что используйте либо Function подход

Map<Integer, String> resultWithFuncMapper =
    list.stream().collect(Collectors.toMap(sampleMapper, Hosting::getName));

, либо метод справочного подхода

 Map<Integer, String> resultWithMethodRef =
    list.stream().collect(Collectors.toMap(Hosting::getId, Hosting::getName));
0 голосов
/ 10 ноября 2019

toMap принимает Function<T, R> в качестве аргумента.

Возможно, вам нужно объявить собственный функциональный интерфейс, как показано ниже

@FunctionalInterface
interface ToIntegerFunction<T> extends Function<T, Integer> {
    Integer apply(T arg);
}
...