Mostrando entradas con la etiqueta interfaz funcional. Mostrar todas las entradas
Mostrando entradas con la etiqueta interfaz funcional. Mostrar todas las entradas

domingo, 30 de diciembre de 2018

Como renombrar ficheros con Java 8

Bueno esta es una entrada más para temas personales que aprender algo propiamente dicho, pero puede ser util igualmente. En este post veremos un pequeño código que nos permitirá renombrar los ficheros: Lo haremos con Java 8 y haciendo uso de Stream y Interfaces funcionales. 

Aquí esta el código de ejemplo:


package es.home.renamer;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class ChangeImageName {
 static String MAIN_PATH = "/home/user/Pictures";
 static String IMAGE_REGEX_1 = "IMG-([0-9]{4})([0-9]{2})([0-9]{2})-WA([0-9]{4}).([\\w]{3})";
 static String PATTERN_FILENAME = "%s-%s-%s %s.%s.%s.%s";
 static Integer COUNT = 0;
 static Pattern PATTERN = Pattern.compile(IMAGE_REGEX_1);
static Consumer<Path> renameFile = new Consumer<Path>() { @Override public void accept(Path path) { Matcher matcher = PATTERN.matcher(path.getFileName().toString()); if (matcher.find()) { String finalName = String.format(PATTERN_FILENAME, matcher.group(1), matcher.group(2), matcher.group(3), "00", "00", String.format("%02d", COUNT++), matcher.group(5)); Path target = Paths.get(path.getParent().toString(), finalName); if(!Files.exists(target)){ try { Files.move(path, target); } catch (IOException e) { e.printStackTrace(); } } } } }; static Predicate<Path> matchRegex = new Predicate<Path>() { @Override public boolean test(Path path) { return path.getFileName().toString().matches(IMAGE_REGEX_1); } }; public static void main(String[] args) { try { try (Stream<Path> paths = Files.walk(Paths.get(MAIN_PATH))) { paths.filter(Files::isRegularFile).filter(matchRegex).forEach(renameFile); } } catch (Exception except) { except.printStackTrace(); } } }

martes, 11 de septiembre de 2018

Stream has already been operated upon or closed

El origen del blog erá crear un librería de post con soluciones de errores comunes que suelo tener, pero ultimamente solo doy la chapa con cosas mas o menos nuevas. Hoy volveremos a retomar esa idea original.

Vamos a hablar de un error que  me dio cuando estuve hacien el post sobre Java 8 y los Streams. Haciendo lo que para mí era algo lógico con los Stream en base a mis conocimientos anteriores, al ejecutar el código me dio el mensaje de error: stream has already been operated upon or closed.

Lo que intentaba era lo siguiente, iterar en un segundo ejemplo sobre el mismo strem:

List<String> list = Arrays.asList("uno", "dos", "tres");
Stream<String> stream = list.stream();
stream.forEach(element -> System.out.println(element));
System.out.println("-------- second example -------");
Stream<String> streaFiltered = stream.filter(element -> element.equals("uno"));
streaFiltered.forEach(element -> System.out.println(element));

El problema viene dado en el funcionamiento de los Steam. Y es que solo tienen permitida una única operación sobre si mismna. Es decir, el Steam será utilizado y cerrado como recurso una vez que realicemos una operación terminal sobre el mismo. Y por tanto no podrá volver a ser utilizado.

la solucion es hacer uso de la interfaz funcional 'Supplier' que nos proveerá del mismo stream todas las veces que queramos.

Supplier<Stream<String>> streamSupplier = () -> Arrays.asList("uno", "dos", "tres").stream();
streamSupplier.get().forEach(element -> System.out.println(element));
System.out.println("-------- second example -------");
Stream<String> streaFiltered = streamSupplier.get().filter(element -> element.equals("uno"));
streaFiltered.forEach(element -> System.out.println(element));

lunes, 3 de septiembre de 2018

Java 8 : las interfaces funcionales, lambda y su generación

Ya hicimos post sobre Java 8 y los steam o las interfaces funcionales. Ahora vamos a intentar hacer uno sobre lambda y su asociación con las intefaces funcioanles.

Cuando hablamos de Lambda, hablamos de expresiones lambda, generadas a través del operador '->'. Estas expresiones lambda a fin de cuenta nos permiten crear funciones anónimas. Y estas funciones a la vez, generan o instancian lo que ya conocemos como interfaces funcionales.

En base a la expresión lambda, generaremos uno u otro tipo de interfaz funcional, pudiendo ser interfaces de características diferentes. Hasta tal punto que en Java 8 se han creado distintos tipo de interfaces funcionales, las cuales puedes ver aquí y vamos a explicar una a una.
  • Consumer
Interfaz funcional que admiten un o dos parámetros y de diferentes tipos primitivos. Estas interfaces devuelven un valor en basé a la implementación interna.

Consumer<String> lambdaObject = (x) -> System.out.println(x.toLowerCase());
lambdaObject.accept("LAMBDA");
//produces : lambda
BiConsumer<String, String> lambdaBiConsumer = (x,y) -> System.out.println(x.toLowerCase() + " " + y.toUpperCase());
lambdaBiConsumer.accept("LAMBDA","lambda");
//produces : lambda, LAMBDA
DoubleConsumer lambdaDoubleConsumer = (x) -> System.out.println(Double.toString(x));
lambdaDoubleConsumer.accept(Double.MIN_VALUE);
//produces : 4.9E-324
  • Functions
Admiten un valor y el retorno no tien porque ser del mismo tipo.

Function<Double, String> lambdaFunction = (d) -> Double.toString(d);
System.out.println(lambdaFunction.apply(1.2));
//produces : 1.2
  • Provider
Aceptan un parámetro y devuelven un valor lógico

Predicate<String> lambdaPredicate = (s) -> "Lambda".equals(s);
System.out.println(lambdaPredicate.test("Lambda"));
// produces : true
  • Supplier
Interfaces que devuelven un valor pero no admiten parámetros

Supplier<String> lambdaSupplier = () ->  Double.toString(1.1);
System.out.println(lambdaSupplier.get());
//produces : 1.1

Con todo esto ya hemos visto un ejemplo básico de que es lambda, para que se usa y que produce. Más adelante haremos otro post con ejemplos más prácticos que le saquen el parte a las expresiones lambda.