Apostila de Java, Capítulo 5 - Um pouco de Arrays

Nesse artigo iremos comentar e resolver os exercícios propostos no capítulo 5, sobre Um pouco de Arrays
Da apostila FJ-11: Java e Orientação a Objetos, da Caelum.

Clique aqui para saber sobre a Caelum e sua apostila.
Recomendamos que tentem ao máximo resolver os exercícios, e só quando conseguir (ou depois de MUITO tentar) veja o código. Caso tenha dificuldades, veja a Solução, que conterá uma explicação a respeito do código, e tente criar seu código.

Programação é criatividade, logo existem mais de uma solução para o mesmo exercício.

Sugerimos que estude as aulas referentes aos Arrays, de nosso curso online Java Progressivo:

Arrays (ou vetores): como declarar, usar e acessar seus elementos
Vídeo-aula: Arrays
Foreach: O laço for para Arrays


Página 71, Exercícios 5.5: Arrays

Enunciados

QUESTÃO 01: 
Volte ao nosso sistema de Funcionario e crie uma classe Empresa dentro do mesmo arquivo .java. A Empresa tem um nome, cnpj e uma referência a uma array de Funcionario, além de outros atributos que você julgar necessário
class Empresa {
// outros atributos
Funcionario[] empregados;
String cnpj;
}

QUESTÃO 02: 
A Empresa deve ter um método adiciona, que recebe uma referência a Funcionario como argumento, e guarda esse funcionário. Algo como:

void adiciona(Funcionario f) {
// algo tipo:
// this.empregados[ ??? ] = f;
// mas que posição colocar?
}
...

Você deve inserir o Funcionario em uma posição da array que esteja livre. Existem várias maneiras para
você fazer isso: guardar um contador para indicar qual a próxima posição vazia ou procurar por uma
posição vazia toda vez. O que seria mais interessante?

É importante reparar que o método adiciona não recebe nome, rg, salário, etc. Essa seria uma ma-
neira nem um pouco estruturada, muito menos orientada a objetos de se trabalhar. Você antes cria um
Funcionario e já passa a referência dele, que dentro do objeto possui rg, salário, etc.

QUESTÃO 03:
Crie uma classe TestaEmpresa que possuirá um método main. Dentro dele crie algumas instâncias de
Funcionario e passe para a empresa pelo método adiciona. Repare que antes você vai precisar criar a
array, pois inicialmente o atributo empregados da classe Empresa não referencia lugar nenhum (null):

Empresa empresa = new Empresa();
empresa.empregados = new Funcionario[10];
//
....

Ou você pode construir a array dentro da própria declaração da classe Empresa, fazendo com que toda
vez que uma Empresa é instanciada, a array de Funcionario que ela necessita também é criada.
Crie alguns funcionários e passe como argumento para o adiciona da empresa:

Funcionario f1 = new Funcionario();
f1.salario = 1000;
empresa.adiciona(f1);
Funcionario f2 = new Funcionario();
f2.salario = 1700;
empresa.adiciona(f2);

Você pode criar esses funcionários dentro de um loop, e dar valores diferentes de salários:
for (int i = 0; i < 5; i++) {
Funcionario f = new Funcionario();
f.salario = 1000 + i * 100;
empresa.adiciona(f);
}

Repare que temos de instanciar Funcionario dentro do laço. Se a instanciação de Funcionario ficasse
acima do laço, estaríamos adicionado cinco vezes a mesma instância de Funcionario nesta Empresa, e
mudando seu salário a cada iteração, que nesse caso não é o efeito desejado.

Opcional: o método adiciona pode gerar uma mensagem de erro indicando quando o array já está cheio.

QUESTÃO 04:
Percorra o atributo empregados da sua instância da Empresa e imprima os salários de todos seus fun-
cionários. Para fazer isso, você pode criar um método chamado mostraEmpregados dentro da classe
Empresa:
...
void mostraEmpregados() {
for (int i = 0; i < this.empregados.length; i++) {
System.out.println("Funcionário na posição: " + i);
// preencher para mostrar o salário!!
}
}
...
Cuidado ao preencher esse método: alguns índices do seu array podem não conter referência para um
Funcionario construído, isto é, ainda se referirem para null. Se preferir, use o for novo do java 5.0.
Aí, através do seu main, depois de adicionar alguns funcionários, basta fazer:
empresa.mostraEmpregados();

QUESTÃO 05 (opcional):
Em vez de mostrar apenas o salário de cada funcionário, você pode chamar o método mostra()  de cada Funcionario da sua array.

QUESTÃO 06 (opcional):
Crie um método para verificar se um determinado Funcionario se encontra ou não como
funcionário desta empresa:

boolean contem(Funcionario f) {
// ...
}

Você vai precisar fazer um for na sua array e verificar se a referência passada como argumento se encontra
dentro da array. Evite ao máximo usar números hard-coded, isto é, use o .length.

QUESTÃO 07 (opcional):
Caso a array já esteja cheia no momento de adicionar um outro funcionário, criar uma nova maior e copiar os valores. Isto é, fazer a realocação já que java não tem isso: uma array nasce e morre com o mesmo length.



Soluções

Vamos começar de baixo, criando a classe Funcionario.
Esta classe é bem simples, pois só vamos usar dois atributos para cada Funcionario: salario e numero.
Onde esse número é de identificação dele na empresa (ou você pode colocar um nome).

Essa classe terá dois métodos:
o getSalario(), que simplesmente retorna o valor do salário do funcionário
e o método mostra(), que exibe as informações completas de cada funcionário.

Agora vamos juntar esses funcionários para formar a empresa e criar a classe Empresa.
Esse classe é um pouco mais complexa, pois trata da empresa e de todos os funcionários.
Esse grupo de funcionários estará armazenado no array 'empregados'.
A empresa possui também duas Strings, que representam o nome da empresa e o CNPJ.
A última variável é o inteiro 'numFuncionarios', que é responsável por armazenar o número de funcionários naquela empresa.

No método construtor padrão criamos o array com tamanho 10, inicializamos o número inicial de funcionários (que é 0, pois nenhum foi adicionado ainda), bem o nome da empresa e o CNPJ, que serão passados por argumento.

Nessa classe empresa será necessário ter o método 'adiciona', que preenche o array 'empregados', como pede a questão 2.
Esse método funciona da seguinte maneira: primeiro testamos se o número de funcionários existentes é menor que 10, pois se for igual ou maior, não podemos mais adicionar ninguém (lembre-se que o número de um array é fixo, e o nosso foi criado com tamanho 10).
Caso satisfaça o teste condicional, vamos adicionar esse novo funcionário na posição 'numFuncionarios' e incrementar essa variável 'numFuncionarios', já que adicionamos um funcionário novo.

Conforme pede o enunciado do exercício 4, criamos também a classe 'mostraEmpregados', que simplesmente corre por todos os empregados existentes e exibe suas informações.

Por fim, a classe Empresa possui o método 'contem' que checa se determinado funcionário está presente na empresa.
Para fazer isso, precisamos comparar a informações do funcionário que estamos buscando dentre todos os funcionários da empresa.
Vamos comparar o atributo 'numero' de cada empregado, pois esse número é único (poderia ser por nome também, caso tenha criado esse atributo na classe Funcionario).
Como foi ensinado o enhanced-for (ou foreach), vamos usar ele para fazer essa comparação dentro do método 'contem'.
A variável 'funcionario', do tipo Funcionario, recebe cada objeto (empregado) do array 'empregados[]' e compara o número de cada um. Caso encontre o número, é porque o funcionário existe na empresa e retorna o valor booleano true. Caso não encontre, ao fim do enhanced-for o método retorna false.

Agora vamos criar a classe principal, que contém o método main: CaelumCap5, na qual vamos fazer todos os testes.
Primeiramente criamos uma empresa: a JP, que tem o nome "Java Progressivo" e CNPJ "12345", que é passado ao método construtor padrão da classe Empresa.
Depois, conforme pede o exercício 3, vamos preencher os valores dos salários dos funcionários. Porém, vamos colocar também uma informação a mais: o número de cada funcionário, que será único.

Preenchido os salários e números dos 10 funcionários, vamos invocar o método 'mostraEmpregados',do objeto JP, e veremos todas as informações dos funcionários na tela.

Como é pedido no exercício 5, vamos mostrar essas mesmas informações, porém percorrendo todo o array de funcionários do objeto JP e usando o método 'mostra', de cada funcionário.

Agora vamos faze dois testes para verificar a funcionalidade do método 'contem': criamos dois funcionários, de números '7' e '11' e checamos se eles estão presentes na empresa (a checagem poderia se feita usando nomes, por exemplo).
Como é de se esperar, o funcionário 7 está na empresa, mas o 11 não.

Como o décimo primeiro não está lá, vamos adicionar ele à empresa.
Mas a empresa só tem espaço para 10 funcionários, o que nos leva a fazer o que é pedido no exercício 7: criamos outro array, agora com 11 elementos.
Primeiro nos copiamos todas as informações do array antigo para o array novo. Agora este possui 10 funcionários.
Por fim, adicionamos o último funcionário.

Para ver como tudo ocorreu bem, fazemos os testes do 'contem' de novo e mostramos todos os funcionários da empresa, através do método 'mostra', de cada funcionário.

Nosso código, dessas 7 questões, fica assim:
Código:
Classe Funcionario.java
public class Funcionario {
    
    double salario;
    int numero;
    
    double getSalario(){
        return this.salario;
    }
    
    void mostra(){
        System.out.println("Empregado de número " + numero + ": " + getSalario());
    }

}


Classe Empresa.java
public class Empresa {
    Funcionario[] empregados;
    String nome,
           cnpj;
    int numFuncionarios;
    
    Empresa(String nome, String cnpj){
        empregados = new Funcionario[10];
        numFuncionarios=0;
        this.nome = nome;
        this.cnpj = cnpj;
    }
    
    void adiciona(Funcionario f){
        if(numFuncionarios < 10){
            empregados[numFuncionarios] = f;
            numFuncionarios++;
        }
    }
    
    void mostraEmpregados(){
        System.out.println("Empresa " + this.nome + " CNPJ " + this.cnpj);
        for(int count=0 ; count < numFuncionarios ; count++){
            System.out.println("Empregado de número " + (count + 1) + ": " + empregados[count].getSalario());
        }
    }
    
    boolean contem(Funcionario f){
        for(Funcionario funcionario: empregados){
            if(funcionario.numero == f.numero){
                return true;
            }
        }
        return false;
    }

}


Classe CaelumCap5.java 

public class CaelumCap5 {

    public static void main(String[] args) {
        Empresa JP = new Empresa("Java Progressivo", "12345");
        
        for (int i = 0; i < 10; i++) {
            Funcionario f = new Funcionario();
            f.salario = 1000 + i * 100;
            f.numero = i+1;
            JP.adiciona(f);
        }
        System.out.println("Método mostraEmpregados:");
        JP.mostraEmpregados();
        
        System.out.println("\nUsando o método 'mostra', de cada funcionário:");
        for(int i=0 ; i < JP.empregados.length ; i++){
            JP.empregados[i].mostra();
        }
        
        Funcionario f7 = new Funcionario();
        Funcionario f11 = new Funcionario();
        f7.numero = 7;
        f11.numero = 11;
        System.out.println("\nContém o funcionario 7? : " + JP.contem(f7));
        System.out.println("Contém o funcionario 11? : " + JP.contem(f11));
        
        //Criando um array de 11 elementos
        Funcionario[] empregados2 = new Funcionario[11];
        
        //Copiando os elementos dos array anterior para o novo array
        for(int i=0 ; i < JP.empregados.length ; i++){
            empregados2[i] = JP.empregados[i];
        }
        
        //Adicionando o empregado 11
        empregados2[10] = f11;

        //checando de novo
        System.out.println("\nContém o funcionario 11? : " + JP.contem(f11));
        
        //Mostrando os empregados
        System.out.println("\nUsando o método 'mostra', de cada funcionário:");
        for(int i=0 ; i < empregados2.length ; i++){
            empregados2[i].mostra();
        }
        

        
    }

}



Página 75, Desafio

Enunciado

QUESTÃO 01:
No capítulo anterior, você deve ter reparado que a versão recursiva para o problema de Fibonacci é lenta porque toda hora estamos recalculando valores. Faça com que a versão recursiva seja tão boa quanto a versão iterativa. (Dica: use arrays para isso)

Solução

QUESTÃO 01:
Vamos criar um array de 70 elementos.
Na posição 0 será armazenado o elemento 0 da série de Fibonacci.
Na posição 1 será armazenado o elemento 1 da série de Fibonacci.
Na posição 2 será armazenado o elemento 2 da série de Fibonacci.
...
Na posição n será armazenado o elemento n da série de Fibonacci.

Onde esse 'n' é o número que o usuário inseriu e, obviamente, deve ser no máximo 69 (pois nosso array é de 70 elementos, ou seja, vai de 0 até 69).

Esse método é mais eficiente, pois uma vez que calculamos um número da série, nós armazenamos ele no array, e para gerar novos números não será necessário recalcular os elementos anteriores, basta usar seus resultados armazenados no array.

Código:
import java.util.Scanner;

public class CaelumFibonacci {

    public static void main(String[] args) {
        //Declarando o array de 100 elementos
        int[] serieFibonacci = new int[100];
        
        //preenchendo os dois elementos inicias
        serieFibonacci[0]=0;
        serieFibonacci[1]=1;
        int n;
        Scanner entrada = new Scanner(System.in);
        
        System.out.print("Que elemento da série deseja calcular [0-99]: ");
        n = entrada.nextInt();
        
        //vamos calcular do elemento 2 até o elemento n
        for(int elemento=2 ; elemento<=n ; elemento++){
            serieFibonacci[elemento] = serieFibonacci[elemento-1] + serieFibonacci[elemento-2];
        }
        
        System.out.println("O valor do elemento " + n + " é: " + serieFibonacci[n]);
    }

}

3 comentários:

Jorge Freitas disse...

Muito boa a resolução desses exercícios da apostila, pois as vezes a Caelum não explica bem e dá uma viajada.

O curso de vocês é meio que o contrário, tentam sempre explicar o máximo possível rs

Parabéns pra equipe!!!

Unknown disse...

Na classe Empresa foi criado um atributo 'empregados' que era um array do tipo 'Funcionario' limitado a 10 posições.

Para poder inserir 11 funcionários, foi criado um novo array 'empregados2' do tipo 'Funcionario' dentro do main.

Após isso foi feito uma checagem na Empresa para verificar se o 11° funcionário existia. Pergunta: Como conseguiu associar este novo array de 11 posições 'empregados2' com o atributo existente na classe 'Empresa'? A classe 'Empresa' não vai continuar possuindo o atributo 'empregados' com 10 posições?

Anônimo disse...

Obrigado, não estava conseguindo resolver esse exercício da apostila, estava com dificuldade.

Dicas e Novidades de Java por e-mail

Sabe quanto custa um bom livro de java?
Entre R$ 100,00 e R$300,00

Sabe quanto custa um bom curso presencial de Java?
Entre R$ 1.500,00 até R$ 4.000,00

Sabe quanto custa estudar pelo Java Progressivo?
Absolutamente nada.

Porém, também precisamos de sua ajuda e apoio.
Para isso, basta curtir nossa Fan Page e clicar no botão G+ do Google.