Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

317
Vistas
¿Por qué mi expresión java lambda no puede funcionar mientras su estilo imperativo funciona correctamente?

Tengo años de experiencia en Java 8 y su lambda. Pero me encontré con un problema loco cuando desarrollé un programa Spark de tamaño mundial.

Aquí tengo una clase de Java, en la que la anotación de datos es de Lombok:

 @Data public class Person implements Serializable { private String name; private Long age; }

Y luego construí una lista de Java que contiene objetos de la clase Persion :

 Person p1 = new Person("sb", 1L); Person p2 = new Person("sth", null); List<Person> list = new ArrayList<>(2); list.add(p1); list.add(p2);

tan bueno tan lejos. Y luego traté de generar un Spark Dataset usando la lista:

 SparkSession session = SparkSession.builder().master("local[1]").appName("SparkSqlApp").getOrCreate(); Encoder<Person> personEncoder = Encoders.bean(Person.class); Dataset<Person> dataset1 = session.createDataset(list, personEncoder); dataset1.foreach(new ForeachFunction<Person>() { // 1 @Override public void call(Person person) throws Exception { System.out.println(person); } }); dataset1.foreach((ForeachFunction<Person>) System.out::println); //2

Tenga en cuenta que el bloque 1 es equivalente al bloque 2 en Java y el bloque 2 está simplificado del bloque 1 por IntelliJ IDEA. La única diferencia es que el bloque 2 usa la expresión lambda.

Sin embargo, cuando ejecuto el programa, el bloque 1 termina bien mientras que el bloque 2 se ejecuta de forma excepcional: ingrese la descripción de la imagen aquí

¿Qué... gran tierra y gran universo? ¿Por qué el motor JVM o Spark hace cosas como esta?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Como se explica en ¿Cuál es la expresión lambda equivalente para System.out::println , la referencia del método System.out::println no es idéntica a la expresión lambda x -> System.out.println(x) .

La referencia del método captura el valor actual de System.out , para invocar println cada vez que se invoca la función, en lugar de evaluar System.out nuevamente cada vez como lo hace el cuerpo de la expresión lambda.

Como también se dijo, esto rara vez marca la diferencia, pero aquí sí lo hace. Cuando intente serializar la función, intentará serializar todos los valores capturados, incluida la instancia de PrintStream leída de System.out durante la creación de instancias. PrintStream no es serializable y sería bastante desafiante implementar un PrintStream serializable que cumpliera con las expectativas.

Pero es importante tener en cuenta que cuando serializa la expresión lambda x -> System.out.println(x) o un objeto de clase equivalente y lo deserializa en un entorno diferente, el System.out que leerá allí se evaluará como un PrintStream diferente al de su entorno original. Esto no importa cuando el marco de computación distribuida se encarga de canalizar todo lo impreso a la salida estándar de regreso al creador.

Pero es importante tener en cuenta que los campos static que no forman parte de los datos serializados pueden tener diferentes contenidos en diferentes entornos en general.

over 4 years ago · Santiago Trujillo Denunciar

0

La interfaz ForeachFunction amplía Serializable . Dataset.foreach(f) puede estar serializando el argumento f . En la siguiente prueba, testBlock1 tiene éxito y testBlcok2 falla (NotSerializableException). Pero no sé por qué.

 public class AAA implements Serializable { @FunctionalInterface public interface ForeachFunction<T> extends Serializable { void call(T t) throws Exception; } @Test public void testBlock1() throws FileNotFoundException, IOException { ForeachFunction<String> functionBody = new ForeachFunction<String>() { public void call(String t) throws Exception { System.out.println(t); } }; try (FileOutputStream fos = new FileOutputStream("data/block1.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(functionBody); // success } } @Test public void testBlock2() throws FileNotFoundException, IOException { ForeachFunction<String> functionBody = System.out::println; try (FileOutputStream fos = new FileOutputStream("data/block2.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(functionBody); // fail (NotSerializableException) } } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda