Ya está aquí la nueva actualización de uno de los lenguajes de programación mas usados, Java 8, y viene cargado de nuevos e interesantes regalos, en linceus queremos dividir esta entrada en dos secciones, la primera especifica las características que incorpora ésta nueva versión, y para aquellos que requieran para su comprensión un poco más de profundidad conceptual, hemos incluído un apartado en el que definimos y ejemplificamos los conceptos que más prestan a confusión para así acabar de leer ésta entrada siendo capaces de comprender de forma general todas las novedades que vienen de la mano con ésta nueva entrega de Java.
Características:
- Incorporación de lambdas como concepto para referirse a un nuevo uso de interfaces funcionales, ésto supondrá una implementación mas fácil de las mismas y de una forma lacónica y escueta en cuanto a interfaces se refiere, además, procurara el desarrollo de funciones anónimas y clausuras (programación funcional). Pero, ¿Qué es una entrada funcional exactamente?, ¿Y las funciones anónimas? lo veremos a continuación en el apartado de conceptos básicos.
- Inclusión de anotaciones, FunctionalInterface. como declaración que forja la interfaz com ointerfaz funcional. (Las anotaciones son usadas por el compilador para evitar errores y agregar a las interfaces métodos)
- Las interfaces ahora tienen potestad para estabñlecer métodos estáticos.Algo muy común en librerías, es que si existe una interfaz Foo, debe existir además una utilitaria (Foos) con métodos estáticosque operen con objetos de Foo (por ejemplo, la interfaz Collection y la clase Collections).gracias a ésta nueva modificación, todos estos métodos pueden ubicarse directamente en la interfaz.
- Ahora es posible implementar de forma predeterminada los métodos, usando la palabra clave default.
- Nuevo paquete java.time que implementa una mejora en la API de fechas con métodos cómo Date.tolnstand(), Date.from(instant) ó Calendar.tolnstant y nuevas clases como Instant, LocalDate, LocalTime, LocalDateTime ó ZonedDataTime.
- Implantación de la API java.util.stream que soporta operaciones propias de la programación funcional sobre flujo de valores. (Ver Streams en conceptos básicos)
- Las anotaciones pueden repetirse en distintos objetos
- Eliminación del espacio PermGen (Espacio de memoria denominado Permanent Generation) a cambio, se inclusye "Metaspaace".
- Uso del método Arrays.parallelSort para ordenar Arrays en paralelo (Múltiples Threads)
- Incluirá un nuevo engine JavaScript (denominado "Nashorn"), que con un abrumador cambio en el rendimiento respecto al actual engine Rhino.
Conceptos básicos:
Lambdas (Interfaces funcionales):
De todas las características que Java 8 incorpora y que modifican sustancialmente el lenguaje, la que debería ser considerada, justamente, como la más significativa, es sin duda alguna la implementación de interfaces funcionales englobadas dentro de el nuevo concepto, lambdas.
Como concepto básico, es necesario conocer que una interfaz es considerada como funcional si declara exactamente 1 método abstracto en su código. Estas interfaces ya son implementadas a día de hoy por librerías. Las interfaces funcionales pueden definir varios métodos de no incluir más de un método abstracto por lo que los métodos prefeterminados (default) no afectan a la hora de aplicar esta norma.
Lambdas (Funciones anónimas): Ahora bién, una expresión lambda es un operador usado para denotar funciones anónimas. Conviene saber qué es una función anónima antes de proseguir, mientras que en otras funciones se necesita crear una clase por cada operador, en las funciones anónimas, ésto no es necesario.
Ejemplo de uso:
Nota#: (a, b) representan los parámetros que recibe la función y ->la función en sí, además, la declaración de retorno (return) se omite dado que sólo tratamos con una expresión.
package
MainClass;
import
calc.*;
/**
*
* @author TEFI
*/
public
class
MainClass {
public
static
void
main(String[] args) {
BinCalc calculadora =
new
BinCalc();
BinCalcIF sumaL = (a, b) -> a + b;
BinCalcIF restaL = (a, b) -> a - b;
System.out.println(
"40 + 2 = "
+ calc.calcular(
40
,
2
, sumaL));
System.out.println(
"20 - 3 = "
+ calc.calcular(
20
,
3
, restaL));
}
}
Ejemplo de expresiones:
String::valueOf x -> String.valueOf(x) Object::toString x -> x.toString() x::toString () -> x.toString() ArrayList::new () -> new ArrayList<>()Lambdas Hacking (English):
Streams:
Comparten un gran parecido con los iteradores. Los valores los valores fluyen y desaparecen por lo que solo pueden recorrerse una vez y pueden ser infinitos, además, pueden ser secuenciales (las acciones transcurren en único thread y de forma meramente secuencial) o paralelos (las acciones son subceptibles de ser ejecutadas simultáneamente dividiendo su lectura en varios threads de ejecución), lo que es configurable desde los métodos stream.sequential() ó stream.parallel().
Existen también dos clases de invocaciones qie los streams pueden ejecutar en su transcurso: "intermedias" y "finales". Las invocaciones intermediascontinúan el flujo, por su parte, las operaciones terminales "consumen"al stream y se tienen que invocar para finalizar la operacion.
Nota #: Los Arrays también suponen un conjunto de valores en una unidad de código pero éstos no son eliminados al ser leídos
Ejemplo de uso:
int sumOfWeights = blocksstream()filter(b -> bgetColor() == RED) mapToInt(b -> bgetWeight()) sum();
MetaSpace (redimensionado dinámico):
Libros Recomendados: Java SE 8 for the Really Impatient
Para más información consulta la documentación de Oracle respecto a Java 8 (English).