- Como conectar?
- Exemplos do meu trabalho: como, sem conhecer uma aula tão útil, criei minha muleta
para bicicleta . - Vejamos outros métodos que achei interessantes.
- Vamos resumir.
0. Como se conectar
Aqueles que andam de mãos dadas comigo já estão mais ou menos familiarizados com Git e Maven, então continuarei confiando nesse conhecimento e não me repetindo. Para quem perdeu meus artigos anteriores ou apenas começou a ler, aqui estão materiais sobre Maven e Git . Claro, sem um sistema de compilação (Maven, Gredl), você também pode conectar tudo manualmente, mas isso é uma loucura hoje em dia e você definitivamente não precisa fazer assim: é melhor aprender imediatamente como fazer tudo corretamente. Portanto, para trabalhar com o Maven, primeiro adicionamos a dependência apropriada:<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.common.version}</version>
</dependency>
Onde ${apache.common.version} é a versão desta biblioteca. A seguir, para importar em alguma classe, adicione import:
import org.apache.commons.lang3.StringUtils;
E é isso, está tudo na bolsa))
1. Exemplos de um projeto real
- método leftPad
O primeiro exemplo geralmente parece tão estúpido agora que é muito bom que meus colegas conhecessem StringUtils.leftPad e me contassem. Qual era a tarefa: o código foi construído de tal forma que era necessário transformar os dados caso eles não chegassem corretamente. Esperava-se que o campo string consistisse apenas em números, ou seja, se seu comprimento for 3 e seu valor for 1, a entrada deverá ser “001”. Ou seja, primeiro você precisa remover todos os espaços e depois cobri-los com zeros. Mais exemplos para deixar clara a essência da tarefa: de “12“ -> “012” de “1“ -> “001” E assim por diante. O que eu fiz? Descrito isso na classe LeftPadExample . Eu escrevi um método que fará tudo isso:
public static String ownLeftPad(String value) {
String trimmedValue = value.trim();
if(trimmedValue.length() == value.length()) {
return value;
}
StringBuilder newValue = new StringBuilder(trimmedValue);
IntStream.rangeClosed(1, value.length() - trimmedValue.length())
.forEach(it -> newValue.insert(0, "0"));
return newValue.toString();
}
Como base, tomei a ideia de que podemos simplesmente obter a diferença entre o valor original e o valor aparado e preenchê-la com zeros na frente. Para fazer isso usei o IntStream para fazer a mesma operação n vezes. E isso definitivamente precisa ser testado. Aqui está o que eu poderia ter feito se soubesse antecipadamente sobre o método StringUtils.leftPad :
public static String apacheCommonLeftPad(String value) {
return StringUtils.leftPad(value.trim(), value.length(), "0");
}
Como você pode ver, há muito menos código e também é usada uma biblioteca confirmada por todos. Para isso criei dois testes na classe LeftPadExampleTest (geralmente quando planejam testar uma classe, eles criam uma classe com o mesmo nome + Teste no mesmo pacote, apenas em src/test/java). Esses testes verificam um método para garantir que ele transforma corretamente o valor e depois outro. É claro que muito mais testes precisariam ser escritos, mas testes não é o tópico principal no nosso caso:
package com.github.javarushcommunity.stringutilsdemo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("Unit-level testing for LeftPadExample")
class LeftPadExampleTest {
@DisplayName("Should transform by using ownLeftPad method as expected")
@Test
public void shouldTransformOwnLeftPadAsExpected() {
//given
String value = "1 ";
String expectedTransformedValue = "0001";
//when
String transformedValue = LeftPadExample.ownLeftPad(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
@DisplayName("Should transform by using StringUtils method as expected")
@Test
public void shouldTransformStringUtilsLeftPadAsExpected() {
//given
String value = "1 ";
String expectedTransformedValue = "0001";
//when
String transformedValue = LeftPadExample.apacheCommonLeftPad(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
}
Posso fazer alguns comentários sobre os testes por enquanto. Eles são escritos usando JUnit 5:
- Um teste será tratado como teste se tiver a anotação apropriada - @Test.
- Se for difícil descrever o funcionamento do teste no nome ou se a descrição for longa e difícil de ler, você pode adicionar a anotação @DisplayName e torná-la uma descrição normal que ficará visível durante a execução dos testes.
- Ao escrever testes, utilizo a abordagem BDD, na qual divido os testes em partes lógicas:
- //dado - bloco de configuração de dados antes do teste;
- //quando é o bloco onde é lançada a parte do código que estamos testando;
- //then é um bloco no qual os resultados do bloco when são verificados.
- método stripStart
Aqui eu precisava resolver um problema com uma linha que poderia ter espaços e vírgulas no início. Após a transformação, eles não deveriam ter um novo significado. A declaração do problema está mais clara do que nunca. Alguns exemplos reforçarão nosso entendimento: “, , books” -> “books” “,,, books” -> “books” b , books” -> “b , books” Como no caso do leftPad, adicionei o Classe StrimStartExample , na qual possui dois métodos. Um - com solução própria:
public static String ownStripStart(String value) {
int index = 0;
List commaSpace = asList(" ", ",");
for (int i = 0; i < value.length(); i++) {
if (commaSpace.contains(String.valueOf(value.charAt(i)))) {
index++;
} else {
break;
}
}
return value.substring(index);
}
Aqui a ideia era encontrar o índice a partir do qual não existem mais espaços ou vírgulas. Se eles não estivessem lá no início, o índice será zero. E o segundo - com solução via StringUtils :
public static String apacheCommonLeftPad(String value) {
return StringUtils.stripStart(value, StringUtils.SPACE + COMMA);
}
Aqui passamos no primeiro argumento informações sobre com qual string estamos trabalhando, e no segundo passamos uma string composta por caracteres que precisam ser ignorados. Criamos a classe StripStartExampleTest da mesma maneira :
package com.github.javarushcommunity.stringutilsdemo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("Unit-level testing for StripStartExample")
class StripStartExampleTest {
@DisplayName("Should transform by using stripStart method as expected")
@Test
public void shouldTransformOwnStripStartAsExpected() {
//given
String value = ", , books";
String expectedTransformedValue = "books";
//when
String transformedValue = StripStartExample.ownStripStart(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
@DisplayName("Should transform by using StringUtils method as expected")
@Test
public void shouldTransformStringUtilsStripStartAsExpected() {
//given
String value = ", , books";
String expectedTransformedValue = "books";
//when
String transformedValue = StripStartExample.apacheCommonLeftPad(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
}
- Método isEmpty
Este método, claro, é muito mais simples, mas isso não o torna menos útil. Ele estende os recursos do método String.isEmpty() , que também adiciona uma verificação de nulo. Para que? Para evitar NullPointerException, ou seja, para evitar chamar métodos em uma variável que seja null . Portanto, para não escrever:
if(value != null && value.isEmpty()) {
//doing something
}
Você pode simplesmente fazer isso:
if(StringUtils.isEmpty(value)) {
//doing something
}
A vantagem deste método é que fica imediatamente claro onde qual método é usado.
2. Análise de outros métodos da classe StringUtils
Agora vamos falar daqueles métodos que, na minha opinião, também merecem atenção. Falando de maneira geral sobre StringUtils , vale dizer que ele fornece métodos nulos seguros análogos aos encontrados na classe String (como é o caso do método isEmpty ). Vamos examiná-los:
- método de comparação
Tal método existe em String e lançará uma NullPointerException se, ao comparar duas strings, uma delas for nula. Para evitar verificações feias em nosso código, podemos usar o método StringUtils.compare(String str1, String str2) : ele retorna um int como resultado da comparação. O que esses valores significam? int = 0 se forem iguais (ou ambos forem nulos). int < 0, se str1 for menor que str2. int > 0, se str1 for maior que str2. Além disso, se você consultar a documentação, o Javadoc deste método apresenta os seguintes cenários:
StringUtils.compare(null, null) = 0
StringUtils.compare(null , "a") < 0
StringUtils.compare("a", null) > 0
StringUtils.compare("abc", "abc") = 0
StringUtils.compare("a", "b") < 0
StringUtils.compare("b", "a") > 0
StringUtils.compare("a", "B") > 0
StringUtils.compare("ab", "abc") < 0
- contém... métodos
Aqui, os desenvolvedores de utilitários se divertiram muito. Qualquer método que você quiser está lá. Resolvi juntá-los:
-
contém é um método que verifica se a string esperada está dentro de outra string. Como isso é útil? Você pode usar este método se precisar ter certeza de que há uma determinada palavra no texto.
Exemplos:
StringUtils.contains(null, *) = false StringUtils.contains(*, null) = false StringUtils.contains("", "") = true StringUtils.contains("abc", "") = true StringUtils.contains("abc", "a") = true StringUtils.contains("abc", "z") = false
Novamente, a segurança NPE (Null Pointer Exception) está presente.
containsAny é um método que verifica se algum dos caracteres presentes na string está presente. Também é uma coisa útil: muitas vezes você precisa fazer isso. Exemplos da documentação:
StringUtils.containsAny(null, *) = false StringUtils.containsAny("", *) = false StringUtils.containsAny(*, null) = false StringUtils.containsAny(*, []) = false StringUtils.containsAny("zzabyycdxx", ['z', 'a']) = true StringUtils.containsAny("zzabyycdxx", ['b', 'y']) = true StringUtils.containsAny("zzabyycdxx", ['z', 'y']) = true StringUtils.containsAny("aba", ['z']) = false
-
containsIgnoreCase é uma extensão útil para o método contains . Na verdade, para verificar tal caso sem este método, você terá que passar por várias opções. E assim apenas um método será utilizado harmoniosamente.
-
containsNone - a julgar pelo nome, você já pode entender o que está sendo verificado. Não deve haver linhas dentro. Uma coisa útil, definitivamente. Pesquisa rápida por alguns caracteres indesejados;). Em nosso bot de telegramas filtraremos obscenidades e não ignoraremos esses métodos engraçados.
E exemplos, onde estaríamos sem eles:
StringUtils.containsNone(null, *) = true StringUtils.containsNone(*, null) = true StringUtils.containsNone("", *) = true StringUtils.containsNone("ab", '') = true StringUtils.containsNone("abab", 'xyz') = true StringUtils.containsNone("ab1", 'xyz') = true StringUtils.containsNone("abz", 'xyz') = false
Alguns exemplos dos documentos:
StringUtils.containsIgnoreCase(null, *) = false
StringUtils.containsIgnoreCase(*, null) = false
StringUtils.containsIgnoreCase("", "") = true
StringUtils.containsIgnoreCase("abc", "") = true
StringUtils.containsIgnoreCase("abc", "a") = true
StringUtils.containsIgnoreCase("abc", "z") = false
StringUtils.containsIgnoreCase("abc", "A") = true
StringUtils.containsIgnoreCase("abc", "Z") = false
- método defaultString
Uma série de métodos que ajudam a evitar a adição de informações extras se a string for nula e você precisar definir algum valor padrão. São muitas opções para todos os gostos. O principal deles é StringUtils.defaultString(final String str, final String defaultStr) - caso str seja nulo, simplesmente passaremos o valor para defaultStr . Exemplos da documentação:
StringUtils.defaultString(null, "NULL") = "NULL"
StringUtils.defaultString("", "NULL") = ""
StringUtils.defaultString("bat", "NULL") = "bat"
É muito conveniente usar ao criar uma classe POJO com dados.
- método deleteWhitespace
Este é um método interessante, embora não existam muitas opções para sua aplicação. Ao mesmo tempo, se tal caso surgir, o método será definitivamente muito útil. Remove todos os espaços da string. Onde quer que esteja essa lacuna, não haverá nenhum vestígio dela))) Exemplos dos documentos:
StringUtils.deleteWhitespace(null) = null
StringUtils.deleteWhitespace("") = ""
StringUtils.deleteWhitespace("abc") = "abc"
StringUtils.deleteWhitespace(" ab c ") = "abc"
- termina com método
Fala por si. Este é um método muito útil: verifica se a string termina com a string sugerida ou não. Muitas vezes isso é necessário. Claro, você mesmo pode preencher o cheque, mas usar um método pronto é claramente mais conveniente e melhor. Exemplos:
StringUtils.endsWith(null, null) = true
StringUtils.endsWith(null, "def") = false
StringUtils.endsWith("abcdef", null) = false
StringUtils.endsWith("abcdef", "def") = true
StringUtils.endsWith("ABCDEF", "def") = false
StringUtils.endsWith("ABCDEF", "cde") = false
StringUtils.endsWith("ABCDEF", "") = true
Como você pode ver, tudo termina com uma linha vazia))) Acho que esse exemplo (StringUtils.endsWith("ABCDEF", "") = true) é só um bônus, porque isso é um absurdo) Também existe um método que ignora caso.
- método igual
Um ótimo exemplo de método nulo seguro que compara duas strings. O que quer que coloquemos lá, a resposta estará lá e sem erros. Exemplos:
StringUtils.equals(null, null) = true
StringUtils.equals(null, "abc") = false
StringUtils.equals("abc", null) = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false
Claro, também existe equalsIgnoreCase - tudo é feito exatamente da mesma maneira, só que ignoramos o caso. Vamos ver?
StringUtils.equalsIgnoreCase(null, null) = true
StringUtils.equalsIgnoreCase(null, "abc") = false
StringUtils.equalsIgnoreCase("abc", null) = false
StringUtils.equalsIgnoreCase("abc", "abc") = true
StringUtils.equalsIgnoreCase("abc", "ABC") = true
- método equalsAny
Vamos prosseguir e estender o método equals . Digamos que em vez de várias verificações de igualdade, queremos realizar uma. Para isso, podemos passar uma string com a qual será comparado um conjunto de strings; se alguma delas for igual à proposta, será VERDADEIRO. Passamos uma string e uma coleção de strings para compará-las (a primeira string com as strings da coleção). Difícil? Aqui estão exemplos dos documentos para ajudá-lo a entender o que isso significa:
StringUtils.equalsAny(null, (CharSequence[]) null) = false
StringUtils.equalsAny(null, null, null) = true
StringUtils.equalsAny(null, "abc", "def") = false
StringUtils.equalsAny("abc", null, "def") = false
StringUtils.equalsAny("abc", "abc", "def") = true
StringUtils.equalsAny("abc", "ABC", "DEF") = false
Também existe equalsAnyIgnoreCase . E exemplos para isso:
StringUtils.equalsAnyIgnoreCase(null, (CharSequence[]) null) = false
StringUtils.equalsAnyIgnoreCase(null, null, null) = true
StringUtils.equalsAnyIgnoreCase(null, "abc", "def") = false
StringUtils.equalsAnyIgnoreCase("abc", null, "def") = false
StringUtils.equalsAnyIgnoreCase("abc", "abc", "def") = true
StringUtils.equalsAnyIgnoreCase("abc", "ABC", "DEF") = true
GO TO FULL VERSION