tutorial streams lambdas expresiones español ejercicios ejemplos java string java-8 java-stream java-9

streams - Java 8/9: ¿Se puede asignar un carácter en una cadena a sus índices(usando flujos)?



lambdas y streams (4)

Dada una String s y un char c , tengo curiosidad si existe algún método para producir una List<Integer> list desde s (donde los elementos dentro de la list representan los índices de c dentro de s ).

Un acercamiento cercano, pero incorrecto sería:

public static List<Integer> getIndexList(String s, char c) { return s.chars() .mapToObj(i -> (char) i) .filter(ch -> ch == c) .map(s::indexOf) // Will obviously return the first index every time. .collect(Collectors.toList()); }

Las siguientes entradas deben producir la siguiente salida:

getIndexList("Hello world!", ''l'') -> [2, 3, 9]


... o en java-9:

Stream.of("Hello world!") .map(Scanner::new) .flatMap(s -> s.findAll("l")) .map(mr -> mr.start()) .forEach(System.out::println);


Se puede hacer con IntStream

public static List<Integer> getIndexList(String s, char c) { return IntStream.range(0, s.length()) .filter(index -> s.charAt(index) == c) .boxed() .collect(Collectors.toList()); }


Una alternativa en Java9 podría ser utilizar la iterate(int seed, IntPredicate hasNext,IntUnaryOperator next) siguiente manera:

private static List<Integer> getIndexList(String word, char c) { return IntStream .iterate(word.indexOf(c), index -> index >= 0, index -> word.indexOf(c, index + 1)) .boxed() .collect(Collectors.toList()); }


Utilizando Java 9, puede buscar de forma iterativa utilizando el último índice como punto de partida, y detenerse cuando no se encuentre ninguna coincidencia:

public static List<Integer> getIndexList(String s, char c) { return IntStream.iterate(s.indexOf(c), i -> s.indexOf(c, i + 1)) .takeWhile(i -> i > -1) .boxed() .collect(Collectors.toList()); }

Descargo de responsabilidad: no he probado esto.