Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

338
Views
¿Las transmisiones de Java pueden reducirse perezosamente de las condiciones del mapa/filtro?

Estoy usando un estilo de programación funcional para resolver la pregunta fácil de Leetcode, Contar el número de cadenas consistentes . La premisa de esta pregunta es simple: cuente la cantidad de valores para los que se cumple el predicado de "todos los valores están en otro conjunto".

Tengo dos enfoques, uno del que estoy bastante seguro de que se comporta como yo quiero y el otro del que estoy menos seguro. Ambos producen la salida correcta, pero idealmente dejarían de evaluar otros elementos después de que la salida esté en un estado final.


 public int countConsistentStrings(String allowed, String[] words) { final Set<Character> set = allowed.chars() .mapToObj(c -> (char)c) .collect(Collectors.toCollection(HashSet::new)); return (int)Arrays.stream(words) .filter(word -> word.chars() .allMatch(c -> set.contains((char)c)) ) .count(); }

En esta solución, según mi leal saber y entender, la declaración allMatch terminará y se evaluará como falsa en la primera instancia de c para la cual el predicado no sea verdadero, omitiendo los otros valores en esa secuencia.


 public int countConsistentStrings(String allowed, String[] words) { Set<Character> set = allowed.chars() .mapToObj(c -> (char)c) .collect(Collectors.toCollection(HashSet::new)); return (int)Arrays.stream(words) .filter(word -> word.chars() .mapToObj(c -> set.contains((char)c)) .reduce((a,b) -> a&&b) .orElse(false) ) .count(); }

En esta solución, se usa la misma lógica, pero en lugar de allMatch , uso map y luego reduce . Lógicamente, después de que un solo valor false proviene de la etapa del map , reduce siempre se evaluará como false . Sé que los flujos de Java son perezosos, pero no estoy seguro de cuándo "saben" cuán perezosos pueden ser. ¿Será esto menos eficiente que usar allMatch o la pereza garantizará la misma operación?


Por último, en este código, podemos ver que el valor de x siempre será 0, ya que después de filtrar solo los números positivos, la suma de ellos siempre será positiva (suponga que no hay desbordamiento), por lo que tomar el mínimo de números positivos y un 0 codificado será 0. ¿La transmisión será lo suficientemente perezosa como para evaluar esto a 0 siempre, o funcionará para reducir cada elemento después del filtro de todos modos?

 List<Integer> list = new ArrayList<>(); ... /*Some values added to list*/ ... int x = list.stream() .filter(i -> i >= 0) .reduce((a,b) -> Math.min(a+b, 0)) .orElse(0);

Para resumir lo anterior, ¿cómo se sabe cuándo el flujo de Java será perezoso? Hay oportunidades perezosas que veo en el código, pero ¿cómo puedo garantizar que mi código será lo más perezoso posible?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

El término real que está pidiendo es cortocircuito

Además, algunas operaciones se consideran operaciones de cortocircuito . Una operación intermedia está en cortocircuito si, cuando se le presenta una entrada infinita, puede producir como resultado un flujo finito. Una operación terminal está en cortocircuito si, cuando se le presenta una entrada infinita, puede terminar en un tiempo finito. Tener una operación de cortocircuito en la tubería es una condición necesaria, pero no suficiente, para que el procesamiento de un flujo infinito termine normalmente en un tiempo finito.

El término “perezosos” solo se aplica a las operaciones intermedias y significa que solo realizan trabajo cuando son solicitados por la operación terminal. Este es siempre el caso, por lo que cuando no encadena una operación de terminal, ninguna operación intermedia procesará ningún elemento.

Averiguar si una operación de terminal está en cortocircuito es bastante fácil. Vaya a la documentación de Stream API y verifique si la documentación de la operación de terminal en particular contiene la oración

Esta es una operación de terminal de cortocircuito.

allMatch lo tiene , reduce no lo tiene .

Esto no significa que dichas optimizaciones basadas en la lógica o el álgebra sean imposibles. Pero la responsabilidad recae en el optimizador de JVM, que podría hacer lo mismo para los bucles. Sin embargo, esto requiere la integración de todos los métodos involucrados para asegurarse de que estas condiciones siempre se apliquen y que no haya ningún efecto secundario que deba conservarse. Esta compatibilidad de comportamiento implica que incluso si el procesamiento se optimiza, un peek(System.out::println) seguiría imprimiendo todos los elementos como si estuvieran procesados. En la práctica, no debe esperar tales optimizaciones, ya que el código de implementación de Stream es demasiado complejo para el optimizador.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!