Uma das coisas que eu acho bem bacana nos bootcamps da DIO é que durante a trilha tem alguns exercícios de código para serem realizados, com um editor ali do lado e algumas condições; uma pegada meio HackerRank assim. É bem bacana que ajuda a sedimentar os conhecimentos adquiridos durante as partes teóricas e não é uma pegada mais complexa como o desafio de projeto: é algo mais simplificado, para testar seu raciocínio lógico e seu conhecimento na linguagem. Assim como no HackerRank, eles te dão alguns trechos já prontos e você desenvolve sua lógica em cima disso.
Essa semana foi uma doideira, então a única coisa que eu consegui fazer foi a resolução dos dois desafios propostos no módulo "Explorando Serviços de Telefonia". Como o patrocinador desse bootcamp é a Claro, muitos dos temas vão ter esse pique de telecom.
Verificação de Serviço Contratado
Enunciado:
Uma concessionária de telecomunicações oferece quatro tipos de serviços: telefonia móvel, telefonia fixa, banda larga e TV por assinatura. Para facilitar o atendimento ao cliente, é necessário implementar um programa que verifique se um cliente específico contratou um determinado serviço. Por exemplo, quando um cliente liga para a central de atendimento e menciona um serviço, o atendente deve ser capaz de rapidamente verificar se esse serviço está contratado pelo cliente.
Entrada:
Duas strings
: Uma com o serviço que a aplicação vai verificar (por exemplo, movel
, fixa
, banda larga
, tv
). A segunda deve conter o nome do cliente e quais produtos ele tem, separados por vírgula (Alice,movel,fixa
)
Saída esperada:
Se o cliente contratou o serviço descrito na primeira entrada, a aplicação deve exibir Sim
. Caso contrário, deve exibir Nao
.
Exemplos:
Entrada | Saída |
---|---|
movel Alice,movel,fixa |
Sim |
fixa Bob,movel,tv |
Nao |
tv Carol,movel,fixa,tv |
Sim |
Código inicial:
import java.util.Scanner;
public class VerificacaoServico {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Entrada do serviço a ser verificado
String servico = scanner.nextLine().trim();
// Entrada do nome do cliente e os serviços contratados
String entradaCliente = scanner.nextLine().trim();
// Separando o nome do cliente e os serviços contratados
String[] partes = entradaCliente.split(",");
String nomeCliente = partes[0];
boolean contratado = false;
// TODO: Verifique se o serviço está na lista de serviços contratados
scanner.close();
}
}
Resolução:
Esse é um desafio relativamente simples. A aplicação recebe uma string
delimitada por vírgulas que é transformada em array
e precisamos descobrir se dentro dela existe uma string
que coincide com outra entrada do usuário, que é o serviço que queremos checar se o cliente possui. Fácil, né?
Pra mim, que tem um histórico de JavaScript e C#, é só usar um método verificador (como o Array.includes()
ou o List.Contains()
). Certo? Errado.
Não existe, em Java, um método como esse na classe Array
. Isso pode ser devido à implementação ser muito mais próxima da que acontece em linguagens de baixo nível (como C), que estabelece que elas devem ser estruturas de dados simples e eficientes. Aparentemente esse tipo de consulta não faz parte das funções essenciais dessa estrutura.
Descobrir essa informação foi um choque. O que o Java espera que eu faça? Que eu escreva um loop for
e cheque manualmente se cada elemento bate com o item que eu estou procurando? Irmão, eu trabalho em tempo integral, tenho uma filha de menos de dois anos e ainda estou estudando Java. Tenho tempo pra isso não, bicho.
Mas eu descobri que desde o Java 8 é possível converter a array
em uma list
e, esta sim, tem o método .contains()
. Então, para a resolução desse problema, é só converter a array
partes
em uma lista, e então verificar se dentro dessa lista existe a string
passada em servico
.
Se existir imprimimos Sim
e em caso contrário, imprimimos Não
.
import java.util.Arrays;
import java.util.Scanner;
public class VerificacaoServico {
public static void main(String[] args) {
//...
// TODO: Verifique se o serviço está na lista de serviços contratados
contratado = Arrays.asList(partes).contains(servico);
System.out.println(contratado ? "Sim" : "Nao");
scanner.close();
}
}
Com isso o exercício está concluído, mas durante a pesquisa que fiz descobri que desde o Java 8 existe uma abstração que ajuda a trabalhar com coleções de dados de uma maneira mais simples e de uma abordagem mais funcional, parecida com o que existe em JavaScript: as streams
.
Assim como com listas, podemos converter o vetor em uma stream
e checar se algum dos elementos presentes nela corresponde ao que foi passado em servico
:
import java.util.Arrays;
import java.util.Scanner;
public class VerificacaoServico {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Entrada do serviço a ser verificado
String servico = scanner.nextLine().trim();
// Entrada do nome do cliente e os serviços contratados
String entradaCliente = scanner.nextLine().trim();
// Separando o nome do cliente e os serviços contratados
String[] partes = entradaCliente.split(",");
String nomeCliente = partes[0];
boolean contratado = false;
contratado = Arrays.stream(partes).anyMatch(servico::equals);
System.out.println(contratado ? "Sim" : "Nao");
scanner.close();
}
}
Podíamos ter feito a verificação passando um callback
para o método .anyMatch(p -> p == servico)
, mas isso checa se p
e servico
não apenas tem o mesmo valor mas também se apontam para o mesmo endereço de memória (ou seja, se são de fato o mesmo objeto). Normalmente, quando lidamos com strings
, essa comparação vai retornar false
mesmo se o valor for igual -- ou seja, um falso negativo. Por isso, a comparação usando servico::equals
é mais adequada, porque compara apenas o valores entre os dois elementos, mais ou menos como o comparador de igualdade do JavaScript (==
).
Com essa alteração, podemos julgar que o exercício está concluído. O que falta é rodar os testes e ver se eles passam:
Bom demais.
Esse exercício me deu outro motivo para reclamar de Java, que é a sintaxe da lambda. O uso da seta simples (->
) ao invés da dupla (=>
) me incomoda muito.
Verificação de Contratação de Combo Completo
Enunciado:
Implemente um sistema que verifique se um cliente de uma empresa de telecomunicações contratou um combo completo de serviços. Um combo completo inclui os três serviços principais oferecidos pela empresa: telefonia móvel, banda larga e TV por assinatura. O sistema deve ler uma lista de serviços contratados pelo cliente e determinar se todos os serviços necessários estão incluídos. Caso todos os três serviços estejam presentes, o sistema deve retornar "Combo Completo". Se faltar qualquer um dos serviços, o sistema deve retornar "Combo Incompleto".
Entrada:
Uma string
contendo os serviços contratados pelo cliente, separados por vírgula. Os valores possíveis são movel
, banda larga
e tv
.
Saída esperada:
Uma string
contendo Combo Completo
se o cliente tiver todos os serviços contratados, Combo Incompleto
do contrário.
Exemplos:
Entrada | Saída |
---|---|
movel,banda larga,tv | Combo Completo |
movel,tv | Combo Incompleto |
banda larga,tv,movel | Combo Completo |
Código inicial:
import java.util.Scanner;
public class VerificacaoComboCompleto {
// Função para verificar se o cliente contratou um combo completo
public static String verificarComboCompleto(String[] servicosContratados) {
// Variáveis booleanas para verificar a contratação de cada serviço
boolean movelContratado = false;
boolean bandaLargaContratada = false;
boolean tvContratada = false;
// TODO: Itere sobre os serviços contratados
for (String servico : servicosContratados) {
}
// TODO: Verifique se todos os serviços foram contratados
if () {
return "Combo Completo";
} else {
return "Combo Incompleto";
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Solicitando ao usuário a lista de serviços contratados
String input = scanner.nextLine();
// Convertendo a entrada em uma lista de strings
String[] servicosContratados = input.split(",");
// Verificando se o cliente contratou um combo completo
String resultado = verificarComboCompleto(servicosContratados);
// Exibindo o resultado
System.out.println(resultado);
// Fechando o scanner
scanner.close();
}
}
Resolução:
De novo, esse é um desafio simples. Para chegar no resultado, apenas alguns passos precisam ser seguidos:
- Iterar sobre a
array
gerada pelo métodomain
a partir dastring
inserida pelo usuário; - Checar se os serviços disponibilizados (descritos nas variáveis booleanas logo acima) foram contratados;
- Em caso positivo, a variável correspondente deve ter seu valor alterado para
true
.
- Em caso positivo, a variável correspondente deve ter seu valor alterado para
- Verificar se todos os serviços estão com o valor
true
. Apesar de ter mais passos, é bem mais direto que o anterior. Podemos começar a resolver esse trem de um jeito bem tosco, com uma série deifs
encadeados: ```java
for (String servico : servicosContratados) {
if(servico.equals("movel")) movelContratado = true;
if(servico.equals("bandaLarga")) bandaLargaContratada = true;
if(servico.equals("tv")) tvContratada = true;
}
E preenchemos a condição do nosso `if`:
```java
if (movelContratado && bandaLargaContratada && tvContratada) {
return "Combo Completo";
} else {
return "Combo Incompleto";
Assim como no primeiro, com essas adições o desafio pode ser considerado como completo, mas esses ifs
, um seguido do outro me incomoda um pouco. Podemos alterar isso pra um switch
pra ficar menos feio:
for (String servico : servicosContratados) {
switch (servico) {
case "movel":
movelContratado = true;
break;
case "banda larga":
bandaLargaContratada = true;
break;
case "tv":
tvContratada = true;
break;
default:
System.out.println("Serviço inválido.");
break;
}
}
Há quem diga que os ifs
são de mais fácil leitura e que o ganho que a otimização traria para um switch
tão pequeno como esse é desprezível. Outros diriam que eu tenho pouca consistência interna, reclamando de checar manualmente strings
em um exercício e fazendo sem um pio em outro.
Pra essas pessoas eu digo:
O código final ficaria então:
import java.util.Scanner;
public class VerificacaoComboCompleto {
// Função para verificar se o cliente contratou um combo completo
public static String verificarComboCompleto(String[] servicosContratados) {
// Variáveis booleanas para verificar a contratação de cada serviço
boolean movelContratado = false;
boolean bandaLargaContratada = false;
boolean tvContratada = false;
for (String servico : servicosContratados) {
switch (servico) {
case "movel":
movelContratado = true;
break;
case "banda larga":
bandaLargaContratada = true;
break;
case "tv":
tvContratada = true;
break;
default:
System.out.println("Serviço inválido.");
break;
}
}
if (movelContratado && bandaLargaContratada && tvContratada) {
return "Combo Completo";
} else {
return "Combo Incompleto";
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Solicitando ao usuário a lista de serviços contratados
String input = scanner.nextLine();
// Convertendo a entrada em uma lista de strings
String[] servicosContratados = input.split(",");
// Verificando se o cliente contratou um combo completo
String resultado = verificarComboCompleto(servicosContratados);
// Exibindo o resultado
System.out.println(resultado);
// Fechando o scanner
scanner.close();
}
}
Que, ao rodar a suite de testes, nos mostra que deu tudo certo:
O código desses (e dos demais) desafios está aqui.
Então é isso, pessoal. Até a próxima!
Top comments (1)
Sênior é outro nível né? Começou agora e já tá dominando a linguagem. Parabéns mano XD. E a seta simples também me incomoda demais kkk.