Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

326
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda