Pular para o conteúdo principal

Guia da certificação Java SE 8 Programmer l - Parte 4: APIs Java

Seja bem-vindo a série de postagens sobre a certificação Java. Como funciona, o que fazer para comprar, marcar o dia da prova e o principal, o que estudar.

Para ver o índice da série e as datas das publicações, acesse este link


Parte 4 – APIs Java

Neste post, vamos dar mais um passo nos detalhes da linguagem quanto as APIs básicas do Java, Arrays, comparação de objetos e manipulação de Srings.

Objetivos do exame

  • Criando e manipulando Strings
  • Diferença entre == e equals()
  • Criando e usando Arrays
  • Usando StringBuilder
  • Usando classes de Data

Criando e manipulando Strings

Você já deve estar bem acostumado a utilizar Strings em seus códigos. Vamos ver o quanto sabe para passar no exame. Existem duas formas de criar uma nova String:
String name = "Joe";
String lastName = new String("Satriani");

Concatenação de Strings

Aqui não temos muitos segredos. Apenas fique atendo ao tipo de dados que esta sendo concatenado.
int one = 1;
String five = "4";
String x = 5 + 3 + one + five;
System.out.println(x);
A saída do código acima é uma String com o valor 94. Também é possível concatenar desta forma:
x += one;
A saída de x agora será 941.

Outra forma de concatenar uma String é utilizar o método concat da classe String. Vamos ver mais abaixo qual o comportamento deste método e como identificar se a String foi concatenada ou não.

Strings são imutáveis

Uma vez criada uma String, ela nunca mais será alterada. Este é o significado de imutável. Se você olhar o código fonte da String, verá que ela é uma classe final e não possui métodos set.

Voltando ao item anterior, vimos que existe outra forma de concatenar uma String. Basta utilizar o método concat da classe String. Porém cuidado, como a String é imutável, podemos nos deparar com uma pergunta do tipo. O que será impresso no código abaixo?
String x = "1";
x.concat("2");
System.out.println(x);
Se você não lembrar que a String é imutável, sua resposta será "12", porem preste atenção no método concat que retorna uma nova String e não altera a String atual. Então a resposta é "1"

Pool de Strings

Para otimizar o uso de memória, o Java guarda os literais das Strings para reuso. Caso mais um uma referência do tipo String tenha o mesmo conteúdo, então eles irão compartilhar o mesmo objeto.
String a = "AB";
String b = "AB";
As variáveis a e b tem o mesmo conteúdo e apontam para o mesmo objeto na memória. Faça o teste com o código abaixo:
System.out.println(a == b);
System.out.println(a.equals(b));
Este é o funcionamento do pool de Strings. Ele verifica que já existe um objeto igual e apenas referencia a nova variável para o mesmo local.
Porém é possível informar a JVM que você deseja criar um novo objeto, por mais que ele tenha o mesmo conteúdo.
String a = "AB";
String b = new String("AB");
Teste agora e verá que a variável a aponta para um objeto diferente que o b. Mais adiante, veremos mais sobre comparação de instancia e de objetos.

Principais métodos da String

Para o exame, você precisará conhecer alguns dos métodos da String e como utilizá-los. Estude e pratique os métodos abaixo:
length()
Retorna o comprimento da sequência de caracteres representados pelo objeto. "AB".length(); // = 2
charAt()
Retorna o valor no índice especificado desta string. "AB".charAt(1);// = "B". Aqui pode ocorrer uma exceção caso o valor especificado seja negativo ou maior que o tamanho da String. 
indexOf()
Retorna o índice dentro dessa sequência da primeira ocorrência do caractere especificado. Este método possui 4 assinaturas diferentes.
substring()
Retorna uma string que é uma substring dessa string. A subsequência começa com o caractere no índice especificado e se estende até o final dessa string. Este método possui 2 assinaturas diferentes.
toLowerCase()
Converte todos os caracteres da String em letras minúsculas usando as regras da localidade padrão. Também é possível passar uma localização para o método.
toUpperCase()
Converte todos os caracteres da String em letras maiúsculas usando as regras da localidade padrão
equals()
Compara a String atual ao objeto especificado. System.out.println("AB".equals("AB"));// true
equalsIgnoreCase()
Compara a String atual ao objeto especificado ignorando maiúsculas e minúsculas.
System.out.println("AB".equalsIgnoreCase("ab"));// true
startsWith()
Testa se a String começa com os caracteres especificados.
System.out.println("AB".startsWith("A"));// true
endsWith()
Testa se a String termina com os caracteres especificados.
System.out.println("AB".endsWith("A")); // false
contains()
Verifica se a String contem a sequencia de caracteres especificada.
System.out.println("ABCD".contains("B")); // true
replace()
Substitui partes da String conforme informado nos parâmetros.System.out.println("ABCD".replace("BC", "AB"));//prints AABD
trim()
Remove espaços em brando no inicio de no fim da String. Não remove espaços entre os caracteres.
System.out.println(" AB CD ".trim());//prints "AB CD"

Encadeamento de métodos

É possível fazer várias chamadas aos métodos String para que retorne uma nova String. E isso é bem comum.
System.out.println(" AB  CD ".trim()
      .toLowerCase().replace("  ", ""));
//prints abcd

StringBuilder

Em um programa Java é comum o uso de muitas Strings, e como elas são imutáveis, logo que uma variável manipula a String original gerando uma nova String, a antiga passa a ser elegível para a coleta de lixo. Dependendo do volume de manipulações, o seu programa pode ficar ineficiente.
Para resolver isso, o Java disponibiliza a classe StringBuilder. Esta classe que manipula muito bem Strings e não é imutável.
StringBuilder numbers = new StringBuilder();
for (int number = 1; number <= 50; number++) {
   numbers.append(number);
}
System.out.println(numbers);
No exemplo acima, estamos montando uma lista de números de 1 a 50. Se fossemos fazer a mesma operação concatenando Strings, teríamos no final, 49 objetos elegíveis para a coleta de lixo.
Ao contrário da String, A StringBuider não retorna um novo objeto, mas ele mesmo.
StringBuilder sb = new StringBuilder("before");
sb.append(" start");
System.out.println(sb); //prints "before start"
Preste atenção no código abaixo. O que será impresso?
StringBuilder a = new StringBuilder("123");
StringBuilder b = a.append("45");
b = b.append("f").append("6");
StringBuilder c = b.append("7");
System.out.println("a=" + a);
System.out.println("b=" + b);
System.out.println("c=" + c);
Copie o código acima e teste em sua IDE. Verifique que existe apenas um objeto StringBuilder e as outras variáveis apontam para ela. O resultado será o mesmo para todas as 3 variáveis.

Criação de uma StringBuilder

Existem algumas formas de se criar uma StringBuilder. A classe possui 4 construtores.
StringBuilder a = new StringBuilder();
StringBuilder b = new StringBuilder("b");
StringBuilder c = new StringBuilder(1);
StringBuilder d = new StringBuilder(c); //CharSequence
Sobre o construtor recebendo um inteiro, não será questionado na prova.

Principais métodos

append()
Principal método da classe, possui diversas assinaturas de método com suporte a vários tipos.
StringBuilder a = new StringBuilder("char");
System.out.println(a.append(1).append(true));
//prints char1true
insert()
Insere uma cadeia de caracteres em um determinado espaço da String.
StringBuilder a = new StringBuilder("char");
System.out.println(a.insert(4, "11"));
//prints char11
No insert() pode ocorrer uma exceção caso o índice seja negativo ou maior que o tamanho da String.
delete() e deleteCharAt()
Oposto do insert(), remove um caractere ou uma sequencia de caracteres da String.
reverse()
Como o próprio nome já sugere, reverte a String.
StringBuilder a = new StringBuilder("char");
System.out.println(a.reverse());
//prints rahc
toString()
Converte o objeto StringBuilder para String.
StringBuilder a = new StringBuilder("char");
String b = a.toString();


Operador de igualdade

O operador == compara números e referência de objetos.
StringBuilder a = new StringBuilder("char");
StringBuilder b = new StringBuilder("char");
System.out.println(a == b); //false
Falso pois StringBuilder é mutável e cada nova referência aponta para um objeto diferente. Se você se perguntar, ok, se eu colocar um toString() vai ser verdadeiro, certo?
System.out.println(a.toString() == b.toString());
Errado, pois o método toString() do StringBuilder cria uma nova instância de String e não usa o pool de Strings. Assim como os métodos de String que manipulam o seu valor. O resultado, caso alterada, será uma nova String.
String a = "A";
String b = "A ".trim();
System.out.println(a);
System.out.println(b);
System.out.println(a == b); //false
Por mais a variável b tenha a mesma String que a, são objetos diferentes. Se a String não sofrer nenhuma alteração, o método irá retornar a mesma instancia:
String a = "A";
String b = "A".trim();
System.out.println(a == b); //true

Método equals()

Para comparar o valor de duas Strings, utilize o método equals(), pois ele compara além da referência, o conteúdo da String.

Arrays

Java fornece uma estrutura de dados, a matriz, que armazena uma coleção sequencial de tamanho fixo de elementos do mesmo tipo. Uma matriz é usada para armazenar uma coleção de dados, mas geralmente é mais útil pensar em uma matriz como uma coleção de variáveis do mesmo tipo.

Array de primitivos

int[] numbers = new int[10];

Forma mais comum de criação de um array. Lembre-se de que um array mesmo sendo de primitivos, ele se torna um objeto. Como definimos um tamanho na criação do array, então podemos trabalhar apenas com o tamanho especificado. Ao declarar um novo array, o Java inicia todos os elementos com os valores padrões para o tipo. 0 para inteiro, false para boolean e null para objetos.
Outra forma de inicializar um array, é informando os literais no momento da sua criação.
int[] numbers2 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Agora o array esta criado e devidamente inicializado. O Java permite que não se informe o tipo e nem a palavra new quando utilizado esta forma. Ele já entende que você quer criar um array com 10 elementos. Desta forma, fica mais legível.
int[] numbers3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Formas de declarar um array

Na prova, é possível que apareçam diferentes formas de declaração de um array.
int[] var;
int var1[];

As chaves podem vir antes ou depois da variável, e podem conter espaços.

Declarações múltiplas

Preste atenção quando ver uma lista de variáveis sendo declaradas na mesma linha. Aprendemos que somente um tipo pode ser declarado. Porém no exemplo abaixo, a variável ids1 é do tipo int e types1 é um array de int:
int[] ids, types;
int ids1, types1[];

Ordenando arrays

Para ordenar um array, pode-se utilizar a classe Arrays do pacote java.util.
String[] alpha = {"x", "w", "n", "a", "b"};
Arrays.sort(alpha);
System.out.println(Arrays.toString(alpha));
//prints: [a, b, n, w, x]

Varargs

Um outro tipo de array pode ser utilizado para passagem de parâmetros. Chamado de (variable arguments).
public static String format(String pattern, Object... arguments)
String message = MessageFormat.format("this is a {0} message {1}", "first", "format");
Iremos explorar mais a utilização das varargs nos próximos posts. Por hora basta saber que ela é um array simples.
Object... arguments = Object[] arguments.

Arrays multidimensionais

Arrays podem conter outros arrays. As declarações abaixo são válidas e declarar arrays de duas dimensões.
int[][] numbers;
int numbers1[][];
int[] numbers2[];

É possível também declarar dimensões diferentes na mesma linha. Assim como pode ser feito em um array normal.
int[] numbers3[], numbers4[][]; //2D and 3D array

Especificando o tamanho

Na declaração também é possível definir o tamanho das dimensões.
int[][] numbers = new int[2][3];

Neste ponto a array não esta inicializada e uma tentativa de uso causará um erro de compilação caso ela esteja declarada como variável local. Caso não esteja declarada como local e não inicializada, causará um erro em tempo de execução quando tentar ler os elementos. O formato abaixo declara, define o tamanho e também inicializa os elementos do array.
int numbers1[][] = {{1,2},{3,4,5}};
Outra forma de declaração, utiliza o new para cada dimensão do array.
int numbers1[][] = new int[2][];
numbers1[0] = new int[3];
numbers1[1] = new int[2];
Traduzindo: Teremos um array de dois elementos que são array. O array 0 tem 3 elementos e o array 1 tem 2 elementos. igual a:
int numbers1[][] = {{0, 0, 0}, {0, 0}};

Percorrendo um array multidimensional

A forma mais comum de percorrer um array de duas dimensões é com o comando for. Também podemos acessar diretamente o elemento da array através do seu índice que inicia em zero. Pense em um array multidimensional como uma tabela. Temos as linhas e as colunas. O código abaixo exemplifica melhor:
int numbers1[][] = {
        {0, 1, 2}, //linha 1 com 3 colunas
        {0, 1}, //linha 2 com duas colunas
        {2, 3}};
Queremos encontrar o valor que está na segunda coluna da terceira linha. Lembre-se que um array sempre inicia do zero.
System.out.println(numbers1[2][1]); //prints 3
Caso tentarmos uma posição fora do tamanho do array, teremos uma exceção:
System.out.println(numbers1[2][2]); //java.lang.ArrayIndexOutOfBoundsException: 2
Tentamos acessar a terceira coluna da linha três, que não existe.

Percorrendo todos os elementos do array

A forma mais comum de percorrer um array é um loop for. No primeiro loop percorremos as linhas e no loop interno as colunas.
for (int i = 0; i < numbers.length; i++) {
    for (int j = 0; j < numbers[i].length; j++) {
        System.out.print(numbers[i][j] + "\t");
    }
    System.out.println("");//new line
}
A outra forma é utilizando o for-each:
for (int[] number : numbers) {
    for (int nr : number) {
        System.out.print(nr + "\t");
    }
    System.out.println("");//new line
}
É uma forma mais simples, porem o mais utilizado na prova ainda é a primeira versão do for.

Entendendo o ArrayList

O que você precisa saber agora de um ArrayList é que ela não tem limite de tamanho e que pode armazenar valores duplicados. Para utilizar o ArrayList, é obrigatória a sua importação.
import java.util.ArrayList;
ArrayList list = new ArrayList();
O código acima cria uma nova instancia de ArrayList sem nenhum elemento dentro. Existem três construtores no ArrayList.
ArrayList() //construtor padrão
ArrayList(int initialCapacity) //inicia o array com capacidade inicial
ArrayList(Collection<? extends E> c) //inicia o array com outra lista
Após o Java 5, foram introduzidos os generics, então a nova forma de se utilizar o ArrayList é:
ArrayList<String> list = new ArrayList();ArrayList<String> list = new ArrayList<String>();
A forma antiga continua valendo. Na segunda linha do exemplo, no lado direito temos novamente o tipo da lista. Esta definição é opcional e as duas formas estão corretas.

Utilizando os métodos do ArrayList

Abaixo, vamos detalhar os métodos que realmente interessam para o exame:
add()
Adiciona um item na lista. Este método possui duas assinaturas:
list.add("AAA");
list.add(0, "BBB");
A primeira assinatura apenas adiciona um item no final da lista, enquanto a segunda adiciona um item em uma posição específica da lista. Esta posição deve ser uma existente ou a próxima da lista, caso contrário você receberá uma exceção java.lang.IndexOutOfBoundsException
Uma vez declarado um ArrayList com um tipo especifico, não é possível incluir outros tipos de Objeto.
ArrayList<String> list = new ArrayList<String>();
list.add(1); //erro de compilação
Caso o tipo seja removido, é possível incluir qualquer tipo de objeto.
ArrayList list = new ArrayList();
list.add(1);
list.add("A");
list.add(true);
remove()
Remove o primeiro objeto que encontrar na lista ou em uma posição específica:
list.remove(true); //remove o primeiro objeto encontrado
list.remove(1); //remove o objeto da posição 1
O método boolean remove(Object o) retorna true caso remova o elemento (objeto existente na lista) e false caso não exista. Nunca teremos uma exceção caso não exista o elemento na lista.
Já o método E remove(int index) pode retornar um IndexOutOfBoundsException caso o elemento não seja encontrado na posição informada. Existe o método boolean removeIf(Predicate<? super E> filter) que será tratado posteriormente. 
set()
Funciona como um replace, trocando um elemento existente por um novo elemento.
list.add(true); //adiciona true na lista
list.set(0, false); //substitui
Qualquer posição informada fora do tamanho da lista, retornará um IndexOutOfBoundsException. Caso a lista for tipada, somente é possível trocar elementos compatíveis.
ArrayList<String> list = new ArrayList();
list.add("A"); //adiciona "A" na lista
list.set(0, 'B'); //erro de compilação
isEmpty()
O método isEmpty() retorna true caso o tamanho da lista for zero. A implementação do método é bem simples.
public boolean isEmpty() {
    return size == 0;
}
size()
Retorna o número de elementos da lista
public int size() {
    return size;
}
clear()
Remove todos os elementos da lista, deixando com o tamanho igual a zero.

contains()
Retorna true se esta lista contiver o elemento especificado. Será utilizado o método equals do objeto contido na lista para comparar o objeto informado. Retorna true quando encontrar o primeiro elemento igual.
boolean contains(Object o)
equals()
Verifica se os dois objetos são do tipo lista e se o conteúdo da lista tem os mesmos objetos.
ArrayList<String> list = new ArrayList();
list.add("A");
ArrayList<String> list1 = list;
System.out.println(list.equals(list1)); //true
Mesmo com objetos diferentes o resultado é true, pois os dois são lista e a comparação de todos os objetos com o método equals retornou true.
ArrayList<String> lista = new ArrayList();
lista.add("A");
ArrayList<String> listb = new ArrayList();
listb.add("A");
System.out.println(lista.equals(listb)); //true
Preste atenção na ordenação da lista. Por mais que a lista tenha os mesmos elementos, o fato de estar em ordem diferente irá fazer com que o equals retorne false.
ArrayList<String> lista = new ArrayList();
lista.add("A");
lista.add("B");
ArrayList<String> listb = new ArrayList();
listb.add("B");
listb.add("A");
System.out.println(lista.equals(listb)); //false

Wrapper Classes

Todo o tipo primitivo possui um correspondente em Objeto. Isso se chama wrapper classes. Para o exame, você precisa conhecer os métodos parse e valueOf das classes wrapper.
Boolean a = Boolean.valueOf("true");
boolean c = Boolean.parseBoolean("false");
Para a classe Boolean, não importa o valor passado por parâmetro. A única situação em que ele vai retornar true é quando a String informada seja "true" sem considerar maiúsculas ou minúsculas.
Boolean a = Boolean.valueOf("tRUe"); //true
Para os tipos Number, você deve tomar um certo cuidado, pois um valor inválido causará uma exceção.
int i = Integer.parseInt("number");
//java.lang.NumberFormatException: For input string: "number"
Mesmo informando um literal válido na declaração de um int, ocorrerá a exceção:
int i = Integer.parseInt("1_000");
//java.lang.NumberFormatException: For input string: "1_000"
Autoboxing
O Java converte automaticamente objetos wrapper para tipos primitivos. Ex:
Boolean a = Boolean.valueOf("true");
boolean b = a;
A única preocupação que você deve ter é referente ao conteúdo do objeto. Caso ele seja null, então no momento da conversão você receberá uma exception
Boolean a = null;
boolean b = a; //java.lang.NullPointerException
Conversão entre Array e List
Você deve saber que a conversão de um Array para List, retorna uma lista fixa de elementos onde não é possível alterar o seu tamanho.
1. String[] array = new String[]{"A", "B", "C"};
2. List<String> list = Arrays.asList(array);
3. System.out.println(list.size()); // 3
4. list.set(1, "X"); // OK
5. System.out.println(list); // [A, X, C]
6. list.add("Z"); //java.lang.UnsupportedOperationException
Na linha 2, estamos convertendo um Array em uma Lista. Verifique que não está sendo criada uma instancia de ArrayList. O tamanho desta lista é 3 e podemos ainda alterar o conteúdo dos elementos, porém na linha 6 ao tentar adicionar um novo elemento, recebemos a exceção. Isto vale para todos os métodos que alteram o tamanho da lista, tais como o remove.
Ordenando Listas
A própria interface List tem um método sort que recebe um Comparator. Para ordenar objetos simples, basta passar null como parâmetro.
List<String> list = new ArrayList<>();
list.add("X");
list.add("F");
list.add("A");
list.sort(null);
System.out.println(list); // [A, F, X]
É possível também utilizar a classe utilitária Collections em vez do método sort da interface List.
Collections.sort(list);

Trabalhando com Datas

A partir do Java 8, a API de Data e Hora foi totalmente reformulada, introduzindo uma série de novas classes. Para o exame, somente as novas API's de data e hora serão mencionadas. Todas as novas classes de manipulação de data do novo modelo estão disponíveis no pacote java.time, então ele precisará ser importado antes do uso.
Para o exame, você precisará conhecer três destas novas classes:
LocalDate: Contém apenas um data, sem informação de hora e time zone
LocalTime: Contém apenas a hora, sem informação de data e time zone.
LocalDateTime: Contém informação de data e hora sem time zone.

O método now() retorna a informação corrente e está disponível nas três classes.
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
2018-07-07
11:20:24.623
2018-07-07T11:20:24.623

Criando uma data específica

Para criar uma data específica, pode-se utilizar o método estático of:
LocalDate date = LocalDate.of(2009, 12, 25);
2009-12-25

O mês não inicia em zero como na API antiga, mas sim com o mês como costumamos a utilizar.
Também é possível utilizar o enum Month para inicializar o mês:
LocalDate date = LocalDate.of(2009, Month.DECEMBER, 25);

Definindo horas

LocalTime pode ser criando informando horas e minutos ou até segundos e nano-segundos:
LocalTime time = LocalTime.of(8, 25);
LocalTime time1 = LocalTime.of(8, 25, 55);
LocalTime time2 = LocalTime.of(8, 25, 55, 200);

Definindo datas com horas

Para isto, utilizamos o método LocalDateTime.of() que possui todas as combinações anteriores. Verifique o javadoc destas classes para mais detalhes.:
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
Lembre-se que as três classes não possuem construtores públicos e a única forma e instancia-los é através dos métodos estáticos.
LocalDateTime d = new LocalDateTime(); // erro de compilação
O mesmo vale se você tentar passar uma mês ou dia inválidos. O código irá compilar, porém irá receber uma exceção:
LocalDate d = LocalDate.of(2009, 12, 32);
//java.time.DateTimeException:
//Invalid value for DayOfMonth (valid values 1 - 28/31

Métodos plus e minus

Para adicionar ou diminuir o tempo nos objetos DateTime, basta utilizar os métodos plus e minus.
LocalDate d = LocalDate.now();
d = d.minusDays(7); //diminui 7 dias
LocalDate d = LocalDate.now();
d = d.plusDays(7); //adiciona 7 dias
Existem alguns métodos para adicionar ou diminuir dias, semanas, meses e anos. Assim como a String, as classes LocalDate, LocalTime e LocalDateTime são imutáveis. É preciso atribuir novamente a variável.
LocalDate d = LocalDate.now();
d.plusDays(7); // não muda nada
É possível fazer estas operações no momento de atribuição da variável.
LocalDateTime dt = LocalDateTime.now()
        .plusDays(1)
        .plusHours(10)
        .plusMonths(1);
Adiciona um dia, um mês e dez horas na data e hora atual.
É preciso saber sobre quais métodos plus e minus são suportados em cada classe. Ex:
LocalDate d = LocalDate.now();
d.plusMinutes(10) //erro de compilação
LocalDate não possui minutos, então o método plusMinutes não existe!

Períodos

Em vez de informar números inteiros para os métodos plus e minus, podemos utilizar a classe Period e encapsular todos os dados para adicionar ou remover um determinado período da data.
LocalDate date = LocalDate.now();
Period period = Period.ofDays(10);
date = date.plus(period);
A classe Period também possui os métodos of() e como as classes de data e hora, é imutável. Outro detalhe para ficar atendo é que os métodos of() podem ser encadeados, mas como eles são estáticos, você sempre terá a última operação válida. Ex:
Period wrong = Period.ofYears(1).ofMonths(10).ofDays(5);
A variável wrong é apenas um período de 5 dias. Anos e meses foram ignorados.
A última coisa sobre período que devemos tomar cuidado é referente a passagem de períodos não permitidos. Ex:
LocalTime time = LocalTime.now();
Period period = Period.ofDays(10);
time = time.plus(period);
//UnsupportedTemporalTypeException: Unsupported unit: Days

Formatando data e hora

Podemos formatar datas e horas de algumas formas. A API de data e hora fornece a classe utilitária DateTimeFormatter.
O Java fornece um formato padrão de saída através da implementação dos métodos toString. Caso seja necessário utilizar outro formato, utilizamos a classe DateTimeFormatter. Abaixo a saída padrão:
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt);
//2018-07-08T11:26:41.185
Abaixo a saída formatada apenas com a data:
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt.format(DateTimeFormatter.ISO_DATE));
//2018-07-08
É possível criar um DateTimeFormat com estilos de formatação pré definidos na classe FormatStyle
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt.format(
        DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)));
//08/07/2018 11:36:30
Caso nenhum dos tipos pré definidos atenda as suas necessidades, é possível informar um padrão de formatação personalizado utilizando o método DateTimeFormatter.ofPattern()
Existe uma lista grande de valores que podem formar o padrão desejável para formatar, porém se passarmos algum inválido, recebera uma exceção.
LocalDateTime dt = LocalDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ofPattern("dd-MM-yyyy");
System.out.println(dt.format(df)); //08-07-2018
Para a prova, é necessário saber diferenciar alguns formatos, principalmente o M do m. M maiúsculo representa o mês, e o m minúsculo representa minutos:
LocalDateTime dt = LocalDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ofPattern("dd-MM-yyyy");
System.out.println(dt.format(df)); //08-07-2018
df = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
System.out.println(dt.format(df)); //08/jul/2018 18:15
Para saber mais:
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

Método parse

É possível informar uma String nos padrões aceitáveis de data e hora e receber uma instância representando aquele formato. Abaixo um exemplo de formato padrão data e hora.
LocalDateTime dt = LocalDateTime.parse("2018-07-08T18:40");
Neste outro exemplo, passamos o formatter para o parser.
DateTimeFormatter df = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
LocalDateTime dt = LocalDateTime.parse("08/07/2018 18:30", df);

Conclusão

Este post foi repleto de detalhes das principais APIs do Java. Revise o conteúdo quantas vezes forem necessárias, faça exercícios e leia a documentação indicada.

Bons estudos e até a próxima!

Comentários

Postagens mais visitadas deste blog

Java Records

  Java Records Imutável, Simples e limpa Esta funcionalidade da linguagem apareceu pela primeira vez na versão 14 como experimental e assim continuou até a versão 15 . Agora liberada de forma definitiva no Java 16 . O objetivo é ser possível ter classes que atuam como portadores transparentes de dados imutáveis. Os registros podem ser considerados tuplas nominais. Ou seja, após criado, um record não pode mais ser alterado. Records oferece uma uma sintaxe compacta para declarar classes que são portadores transparentes para dados imutáveis superficiais visando reduzir significamente o detalhamento dessas classes e irá melhorar a capacidade de leitura e manutenção do código. Vamos seguir um exemplo de uma classe chamada Pessoa . O primeiro exemplo vamos utilizar o modo tradicional. public class Pessoa { private String nome; private int idade; public Pessoa (String nome, int idade) { super (); this .nome = nome; this .idade = idade; } public String getNo

Java 8 ao 18: Mudanças mais importantes na plataforma Java

    Vamos rever muitas das mudanças mais importantes na plataforma Java que aconteceram entre a versão 8 (2014) e 18 (2022)   O Java 8 foi lançado em março de 2014 e o Java 18 em março de 2022. São 8 anos de progresso, 203 JEPs (JDK Enhancement Proposals ), entre essas duas versões. Neste post, revisaremos as mudanças mais importantes e discutiremos os benefícios e desafios da adoção de versões mais recentes do JDK para novos aplicativos e para os mais antigos compilados com versões mais antigas. Desde a versão 9, o Java tem novos recursos a cada 6 meses e é muito difícil acompanhar essas novas mudanças. A maioria das informações na internet descreve as mudanças entre as duas últimas versões do Java. No entanto, se você estiver em uma situação semelhante à minha, não está usando uma das versões mais recentes do Java, mas uma das várias versões anteriores (Geralmente 8 ou 11 que são as versões de suporte estendido). Então é útil saber quais novos recursos foram adicionados d

O suporte de longo prazo e o que o LTS significa para o ecossistema Java

A arte do suporte de longo prazo e o que o LTS significa para o ecossistema Java Aqui está o que o Java 17 tem em comum com o Java 11 e o Java 8. Em junho de 2018, há pouco mais de três anos, a Oracle e outros participantes do ecossistema Java anunciaram uma mudança no modelo de cadência de lançamento para Java SE. Em vez de ter um lançamento principal planejado a cada dois ou quatro anos (que geralmente se torna de três a quatro anos), um novo modelo de lançamento de recursos de seis meses seria usado: a cada três anos, um lançamento seria designado como Long-Term Support (LTS) e receba apenas atualizações trimestrais de segurança, estabilidade e desempenho. Esse padrão foi emprestado descaradamente do modelo de lançamento do Mozilla Firefox, mas o ajustou para ficar mais alinhado com os requisitos de uma plataforma de desenvolvimento. A primeira versão do Java lançada sob esse modelo foi o Java SE 11. O lançamento do Java SE 17, o segundo lançamento do LTS sob o novo