24-04-2023
10 dicas avançadas de desenvolvimento em Java
por Juliane Bazilewitz, Backend Developer @ Xpand IT
Java é uma das linguagens de programação mais utilizadas no mundo. Há novas versões a serem frequentemente lançadas, com muitos novos recursos para desfrutarmos.
Neste blog post, apresentamos-te 10 hacks de Java que podem ser usados para melhorar o teu trabalho como developer de Java. Lembre-te: work smart, not hard!
1. Usa Streams para Data Processing
Streams foi introduzido no Java 8 e usa operações de estilo funcional para processar dados. Isto permite fazer várias operações em certas coleções com código mais simples. As operações comuns são: filtrar, mapear, reduzir, localizar, combinar e classificar. A origem pode ser uma coleção, operação IO, ou uma matriz que fornece os dados para um fluxo.
A interface Stream é definida no pacote java.util.stream.
Exemplo:
List<String> cities = Arrays.asList( "Paris", "Barcelona", "Coimbra", "Cairo", "Beijing"); cities.stream() // Paris, Barcelona, Coimbra, Cairo, Beijing .filter(a -> a.startsWith("C")) // Coimbra, Cairo .map(String::toUpperCase) // COIMBRA, CAIRO .sorted() // CAIRO, COIMBRA .forEach(System.out::println); // CAIRO, COIMBRA
Neste exemplo, estamos a filtrar as cidades que começam com a letra “C”. Também fazemos a conversão para maiúsculas e classificamos antes de imprimir o resultado.
Output:
CAIRO, COIMBRA
2. Usa Optional para Nullable Objects
Optional API foi introduzido no Java 8. Se és Java Developer, deverás ter tido dificuldades em obter NullPointerException.
Exemplo:
Object obj = null; // created null variable obj.toString(); // method call over null variable
Ao usares Optional, proteges o teu código contra exceções indesejadas de null pointer. A maneira principal de evitar estas exceções de null pointer ao utilizar Optional, é usar um optional vazio. Também podemos processar sobre o objeto se o este estiver present ou null.
Exemplo de um optional vazio:
Optional<String> objEmpty = Optional.empty(); assertFalse(objEmpty.isPresent());
Exemplo de nullable value:
Object obj = null; Optional<Object> objOpt = Optional.ofNullable(obj); System.out.println(objOpt.isPresent()); // prints false
Exemplo de non-null value:
Optional<Object> opt = Optional.of(new Object());
3. Usa Builder Pattern para objetos complexos
Builder é um padrão de design criacional. Com o padrão Builder, podemos criar representações diferentes de um objeto usando o mesmo processo de construção, especialmente para objetos mais complexos.
Então, onde podemos usar o Builder Pattern? Builder Pattern é usado quando é necessário usar um construtor com uma longa lista de parâmetros ou quando há uma longa lista de construtores com diferentes parâmetros. Também é usado quando a criação do objeto contém parâmetros opcionais.
Exemplo:
Use List<DocumentAction> availableActions = new DocumentActionEvaluator() .withDocument(document) .withSource(source) .withUser(user) .eval();
Em vez de:
List<DocumentAction> availableActions = new ArrayList<>(); availableActions.setDocument(document); availableActions.setDocument(source); availableActions.setDocument(user);
4. Usa StringBuilder para concatenação de strings
StringBuilder fornece uma matriz de utilitários de construção de strings que facilitam a manipulação de strings [sequência de caracteres]. StringBuilder é usado para executar a operação de concatenação. O mesmo pode ser feito através do operador “+”, mas o StringBuilder tem uma forma mais eficiente.
Exemplo:
StringBuilder strB = new StringBuilder(100); strB.append("Xpand-IT") .append(" is a") .append(" good") .append(" place") .append(" to work"); assertEquals("Xpand-IT is a good place to work", strB.toString());
5. Usa Java Agents para alterar o teu código
Imagine que o teu código já está em produção e precisas de entender algum problema que está a acontecer no momento? Em vez de fazer alterações para adicionar logs no meio do código, podes usar Java Agents.
Os Java Agents fazem parte da API de Java Instrumentation – uma técnica utilizada para alterar um aplicação existente adicionando código em tempo de execução. Faz parte da biblioteca desde o JDK 1.5.
Para saberes mais detalhes sobre como criar e carregar um Java Agent, podes ler este post da Baeldung.
6. Usa Generics
O Java Generics foi introduzido no JDK 5.0. Por que usar Generics? Java Generics permite criar uma única classe, interface e método que pode ser usado com diferentes tipos de dados (objetos). Sem genéricos, muitos dos recursos que usamos hoje em Java não seriam possíveis.
Classe de tipo Generic:
class Main { public static void main(String[] args) { // initialize generic class with Integer data GenericsClass<Integer> intObj = new GenericsClass<>(5); System.out.println("Generic Class returns: " + intObj.getData()); // initialize generic class with String data GenericsClass<String> stringObj = new GenericsClass<>("Java Programming"); System.out.println("Generic Class returns: " + stringObj.getData()); } } // create a generics class class GenericsClass<T> { // variable of T type private T data; public GenericsClass(T data) { this.data = data; } // method that return T type variable public T getData() { return this.data; } }
Output:
Generic Class returns: 5 Generic Class returns: Java Programming
Método Generics type:
public <T> List<T> fromArrayToList(T[] a) { return Arrays.stream(a).collect(Collectors.toList()); } public void testFromArrayToListGenericMethod() { Integer[] intArray = {1, 2, 3, 4, 5}; List<String> stringList = fromArrayToList(intArray, Object::toString); assertThat(stringList, hasItems("1", "2", "3", "4", "5"));
7. Usa Varargs para passar um número variável de argumentos
Varargs foram introduzidos no Java 5. É uma forma abreviada para argumentos de comprimento variável. Isto permite que o método aceite um número arbitrário de argumentos do tipo de dados especificado.
Sintaxe de varargs: Um argumento de comprimento variável é especificado por três pontos (…).
Exemplo:
public class VarargsExample { // Method that accepts a variable number of integer arguments public static void printNumbers(int… numbers) { System.out.println("Number of arguments: " + numbers.length); // get the number of arguments passed System.out.print("Arguments: "); for (int number : numbers) { System.out.print(number + " "); } System.out.println(); } public static void main(String[] args) { printNumbers(1); printNumbers(4, 7, 2); printNumbers(5, 8, 3, 10, 15); printNumbers(); // This will work as well, with zero arguments } } }
8. Usa expressões regulares para pesquisar e manipular texto
Uma expressão regular (regex) define um padrão de pesquisa para strings de maneira mais precisa do que os métodos regulares (ou outros semelhantes). A expressão regular pode ser usada para pesquisar, editar ou manipular texto. Uma expressão regular não é específica da linguagem, mas difere ligeiramente para cada linguagem. Isto tem uma longa curva de aprendizagem, mas ao dominares, certamente vais começar a usar a toda a hora.
As classes Java Regex estão presentes no pacote java.util.regex que tem três classes:
- Matcher Class – Define um padrão (para ser usado numa pesquisa)
- Classe de padrão – Usado para procurar o padrão
- Classe PatternSyntaxException – Indica erro de sintaxe num padrão de expressão regular
Exemplo com a classe Matcher:
Pattern pattern = Pattern.compile("Xpand-IT", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher("Visit Xpand-IT blog!"); boolean matchFound = matcher.find(); if(matchFound) { System.out.println("Match found"); } else { System.out.println("Match not found"); } // Outputs Match found
9. Usa ternary operator para simplificar if-else statements
O ternary operator é usado no lugar das instruções if-else, if-elseif e switch-case. O ternary operator consiste numa condição avaliada como verdadeira ou falsa, mais um valor que é devolvido se a condição for verdadeira e outro valor que é devolvido se a condição for falsa.
O ternary operator aumenta a concisão e a legibilidade do código.
Exemplo:
//Regular if-else if(var1) { variable = var2; } else { variable = var3; } // ternary operator variable = var1 ? var2 : var3;
10. Try-with-resources
A instrução Try-with-resources é uma instrução try que declara um ou mais recursos. O recurso é como um objeto que deve ser fechado após o fecho do programa. Ao usarmos try-with-resources, substituímos o bloco try-catch-finally tradicional.
Um bloco try-with-resources ainda pode ter os blocos catch e finally , que funcionarão da mesma forma que um bloco try tradicional.
try(FileInputStream input = new FileInputStream("file.txt")) { int data = input.read(); while(data != -1){ System.out.print((char) data); data = input.read(); }
Conclusão
Aqui estão algumas dicas para otimizar, melhorar o desempenho do teu código e torná-lo mais legível.
Existem várias maneiras de resolver problemas.
Leave a comment
Comments are closed.