En mi ejemplo, trato de crear una tabla ASCII a partir de una secuencia de caracteres. He conseguido hacerlo con una List
de las cadenas, pero no pudo con un conjunto de caracteres.
Me aparece un error que Character::hashCode
no se puede resolver en Collectors.toMap()
.
Error:(26, 17) java: method collect in interface java.util.stream.IntStream cannot be applied to given types;
required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R>
found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Map<java.lang.Object,java.lang.Object>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
Error:(26, 42) java: incompatible types: cannot infer type-variable(s) T,K,U,T
(argument mismatch; invalid method reference
incompatible types: java.lang.Object cannot be converted to char)
¿Hay una manera de hacerlo?
public class JavaCollectToMapEx2 {
public static void main(String[] args) {
// list of ASCII characters
var chars = List.of("a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z");
// CharSequence chars2 = "abcdefghijklmnopqrstuvwxyz";
char[] letters = "abcdefghijklmnopqrstuvwxyz".toCharArray();
// Map to represent ASCII character table
Map<Integer, String> asciiMap = chars.stream()
.collect(Collectors.toMap(String::hashCode, Function.identity()));
Map<Integer, Character> asciiMap2 = CharBuffer.wrap(letters).chars()
.collect(Collectors.toMap(Character::hashCode, Function.identity()));
System.out.println(asciiMap);
System.out.println(asciiMap2);
}
}
.chars()
le está dando una IntStream
, que es una corriente de primitiva int
, y no un flujo de caracteres ( más información ). Es por esto que no hay referencias de métodos de Character
trabajo de la voluntad.
Para lograr lo que está buscando, usted necesitará una Stream<Character>
primera:
Map<Integer, Character> asciiMap2 = CharBuffer.wrap(letters)
.chars()
.mapToObj(e -> (char) e)
.collect(Collectors.toMap(e -> e.hashCode(), Function.identity()));
Ahora, usted todavía tiene el tema del uso de una referencia método para obtener el código hash. No se puede utilizar Character::hashCode
porque es ambigua en cuanto a qué método que desee, ya que hay dos que son posibles:
- La anulación del objeto # hashCode,
- El método estático
int hashCode(char value)
Se puede ver en el código, que tanto satisface el primer argumento toMap()
:
Function<Character, Integer> f1 = e -> Character.hashCode(e);
Function<Character, Integer> f2 = e -> e.hashCode();
Para resolver esto, se puede utilizar Object::hashCode
para la llamada a un método no estático.