Prática: Processamento de Strings
Esta lição é a prática hands-on da Fase 2, consolidando habilidades de processamento de strings através de 5 projetos.
Projeto 1: Inversão de String
Habilidades usadas: StringBuilder, String.toCharArray().
Requisitos
Escreva um método para inverter uma string.
Implementação
public class StringReverse {
// Método 1: StringBuilder
public static String reverse1(String str) {
if (str == null) return null;
return new StringBuilder(str).reverse().toString();
}
// Método 2: Array de caracteres
public static String reverse2(String str) {
if (str == null) return null;
char[] chars = str.toCharArray();
int left = 0, right = chars.length - 1;
while (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
return new String(chars);
}
// Método 3: Recursão
public static String reverse3(String str) {
if (str == null || str.length() <= 1) {
return str;
}
return reverse3(str.substring(1)) + str.charAt(0);
}
public static void main(String[] args) {
String s = "Hello, World!";
System.out.println("Original: " + s);
System.out.println("Reverso 1: " + reverse1(s));
System.out.println("Reverso 2: " + reverse2(s));
System.out.println("Reverso 3: " + reverse3(s));
}
}
Saída:
Original: Hello, World!
Reverso 1: !dlroW ,olleH
Reverso 2: !dlroW ,olleH
Reverso 3: !dlroW ,olleH
Projeto 2: Contagem de Palavras
Habilidades usadas: String.split(), loop for-each.
Requisitos
Conte o número de palavras em uma string.
Implementação
public class WordCount {
public static int countWords(String str) {
if (str == null || str.trim().isEmpty()) {
return 0;
}
// Dividir por espaços em branco, trim remove espaços início/fim
String[] words = str.trim().split("\\s+");
return words.length;
}
public static void main(String[] args) {
System.out.println(countWords("Hello World")); // 2
System.out.println(countWords(" Hello World ")); // 2
System.out.println(countWords("Java is awesome")); // 3
System.out.println(countWords("")); // 0
System.out.println(countWords(null)); // 0
}
}
Projeto 3: Detecção de Palíndromo
Habilidades usadas: StringBuilder, dois ponteiros.
Requisitos
Determine se uma string é um palíndromo (lê-se igual de frente para trás).
Implementação
public class Palindrome {
// Método 1: Inversão com StringBuilder
public static boolean isPalindrome1(String str) {
if (str == null) return false;
String reversed = new StringBuilder(str).reverse().toString();
return str.equals(reversed);
}
// Método 2: Dois ponteiros
public static boolean isPalindrome2(String str) {
if (str == null) return false;
int left = 0, right = str.length() - 1;
while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
// Ignorar maiúsculas/minúsculas e caracteres não alfanuméricos
public static boolean isPalindromeIgnore(String str) {
if (str == null) return false;
String cleaned = str.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
return isPalindrome2(cleaned);
}
public static void main(String[] args) {
System.out.println(isPalindrome1("racecar")); // true
System.out.println(isPalindrome1("hello")); // false
System.out.println(isPalindromeIgnore("A man, a plan, a canal: Panama")); // true
}
}
Projeto 4: Cálculo de Datas
Habilidades usadas: LocalDate, ChronoUnit, Period.
Requisitos
Calcule a diferença em dias, anos, meses e dias entre duas datas.
Implementação
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class DateCalculator {
// Calcular dias entre
public static long daysBetween(LocalDate start, LocalDate end) {
return ChronoUnit.DAYS.between(start, end);
}
// Calcular anos, meses, dias entre
public static Period periodBetween(LocalDate start, LocalDate end) {
return Period.between(start, end);
}
// Verificar ano bissexto
public static boolean isLeapYear(int year) {
return LocalDate.of(year, 1, 1).isLeapYear();
}
// Obter dias no mês
public static int daysInMonth(int year, int month) {
return LocalDate.of(year, month, 1).lengthOfMonth();
}
public static void main(String[] args) {
LocalDate start = LocalDate.of(2026, 1, 1);
LocalDate end = LocalDate.of(2026, 12, 31);
System.out.println("Dias entre: " + daysBetween(start, end)); // 364
Period period = periodBetween(start, end);
System.out.println("Período: " + period); // P11M30D
System.out.println("2026 é bissexto: " + isLeapYear(2026)); // false
System.out.println("2024 é bissexto: " + isLeapYear(2024)); // true
System.out.println("Dias em Fev 2026: " + daysInMonth(2026, 2)); // 28
}
}
Projeto 5: Criptografia de Strings
Habilidades usadas: charAt(), StringBuilder, aritmética ASCII.
Requisitos
Implemente uma cifra de César simples (desloque cada letra em 3 posições).
Implementação
public class CaesarCipher {
public static String encrypt(String text, int shift) {
StringBuilder result = new StringBuilder();
for (char c : text.toCharArray()) {
if (Character.isLetter(c)) {
char base = Character.isUpperCase(c) ? 'A' : 'a';
// Criptografar: (char - base + shift) % 26 + base
char encrypted = (char) ((c - base + shift) % 26 + base);
result.append(encrypted);
} else {
result.append(c);
}
}
return result.toString();
}
public static String decrypt(String text, int shift) {
return encrypt(text, 26 - shift);
}
public static void main(String[] args) {
String original = "Hello, World!";
int shift = 3;
String encrypted = encrypt(original, shift);
String decrypted = decrypt(encrypted, shift);
System.out.println("Original: " + original);
System.out.println("Criptografado: " + encrypted); // Khoor, Zruog!
System.out.println("Descriptografado: " + decrypted); // Hello, World!
}
}
Prática Adicional
Exercício 1: Frequência de Caracteres
import java.util.HashMap;
import java.util.Map;
public class CharFrequency {
public static Map<Character, Integer> frequency(String str) {
Map<Character, Integer> map = new HashMap<>();
for (char c : str.toCharArray()) {
map.put(c, map.getOrDefault(c, 0) + 1);
}
return map;
}
public static void main(String[] args) {
String s = "hello world";
Map<Character, Integer> freq = frequency(s);
for (Map.Entry<Character, Integer> entry : freq.entrySet()) {
System.out.println("'" + entry.getKey() + "' : " + entry.getValue());
}
}
}
Exercício 2: Conversão CamelCase
public class CamelCase {
// Underscore para camelCase
public static String toCamelCase(String str) {
StringBuilder result = new StringBuilder();
boolean capitalizeNext = false;
for (char c : str.toCharArray()) {
if (c == '_') {
capitalizeNext = true;
} else {
if (capitalizeNext) {
result.append(Character.toUpperCase(c));
capitalizeNext = false;
} else {
result.append(c);
}
}
}
return result.toString();
}
// camelCase para underscore
public static String toSnakeCase(String str) {
StringBuilder result = new StringBuilder();
for (char c : str.toCharArray()) {
if (Character.isUpperCase(c)) {
result.append('_');
result.append(Character.toLowerCase(c));
} else {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
System.out.println(toCamelCase("hello_world")); // helloWorld
System.out.println(toSnakeCase("helloWorld")); // hello_world
}
}
❓ Perguntas Frequentes
P: Operações com strings são lentas—o que devo fazer? R: Use StringBuilder para concatenações em massa. Use regex para buscas frequentes.
P: Como lidar com strings nulas e vazias? R: Verifique nulas e vazias no início do seu método. Retorne um valor padrão razoável ou lance uma exceção.
P: Como aprender regex? R: Comece com o básico (. * + ? [] ()), depois aprenda gradualmente o uso avançado.
📖 Resumo
- Inversão de string: StringBuilder.reverse() ou dois ponteiros
- Contagem de palavras: split("\s+") depois contar
- Palíndromo: comparação reversa ou dois ponteiros
- Cálculo de datas: LocalDate + ChronoUnit/Period
- Cifra de César: aritmética ASCII
📝 Exercícios
- Compressão de string: Comprima "aaabbbcc" para "a3b3c2"
- Validação de email: Determine se uma string é um formato de email válido
- Classe utilitária de data: Escreva uma classe DateUtils com métodos para cálculo de idade, dias entre, formatação, etc.
Próxima Lição
Na próxima lição, passaremos para a Fase 3 e aprenderemos sobre Classes e Objetos — entrando no mundo da programação orientada a objetos.



