Duvida quanto a arrays de classe

Boa tarde galera! estou com uma duvida quanto a um problema:
Tenho q criar uma método que tem como parâmetro o tamanho do array(int) e que retorna uma class de arrays.
Tenho que criar um array novo e passar o velho para o novo.
As duvidas são:
1- eu posso passar uma variável para ser o tamanho de uma array?
2- Como funcionario esse return?
3- Existe um jeito mais simples de fazer isso?

Desde ja obrigado =D

Esse seria o método:

Funcionario novaLista(int x){
	Funcionario[] f = new Funcionario[int];
	for(int i=0; i<this.empregados.length; i++ ){
		f[i] = this.empregados[i];
	}
	System.out.println("Nova lista com espaços " + x);
	return f;
}

Não vejo sentido em vc receber o tamanho do array por parâmetro, uma vez que o o tamanho que importa é do atributo empregados. Vou deixar três sugestões pra vc, aí vc escolhe a que melhor lhe convém.

Laço de repetição for

Funcionario[] novaLista(){
  Funcionario[] f = new Funcionario[empregados.length]; // agora seu novo array tem o tamanho exato do array existente
  for(int i = 0; i < empregados.length; i++){
    f[i] = empregados[i];
  }
  return f;
}

A segunda forma seria pelo método System.arraycopy(). Este método recebe 5 argumentos, veja a documentação:

System.arraycopy()

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

src: é o array que será copiado
srcPos: posição inicial da cópia
dest: array de destino que receberá os valores da fonte
destPos: posição inicial de alocação dos novos elementos
length: quantidade de elementos que serão copiados

Sabendo disto, podemos traduzir que:

src: empregados
srcPos: queremos todos os elementos, logo a posição inicial de cópia será a 0
dest: f
destPos: queremos uma cópia fiel de empregados, então a posição inicial será 0
length: queremos todos os elementos, então a quantidade de elementos será o tamanho do array de empregados

Implementando:

Funcionario[] novaLista(){
  Funcionario[] f = new Funcionario[empregados.length];
  System.arraycopy(empregados, 0, f, 0, empregados.length);
  return f;
}

O legal desta forma é que o System.arraycopy() deixa as coisas mais interessantes por permitir uma flexibilidade maior na estratégia de manipulação, como por exemplo, copiar uma parte específica do array. Veja:

String[] a = {"aaa", "asaf", "G", "U", "J", "sasa"};
String[] b = new String[3];
System.arraycopy(a, 2, b, 0, 3); 
System.out.print(b[0] + b[1] + b[2]); //GUJ

Por fim, o método Arrays.copyOf()

Este método recebe dois parâmetros:

src: array que será copiado
length: quantidade de elementos a ser copiado

O length neste caso atua de forma diferente, ele pega os “n” primeiros elementos do array. Se eu tiver um array de tamanho 5 e passar o length como 2, somente os dois primeiros elementos do array serão copiados.

Funcionario[] novaLista(){
  Funcionario[] f = Arrays.copyOf(empregados, empregados.length);
  return f;
}

Conclusão

O for e o System.arraycopy() não alocam o array de destino na memória, pois é necessário que estes espaços já estejam previamente alocados. Já o Arrays,copyOf() faz a alocação do array de destino na memória, com isso, pode-se afirmar que o desempenho do último método é inferior ao dos dos primeiros. Testemos com um array de tamanho 999999.

public class Main {

    public static void main(String... args) {
        long tempoInicial;
        long tempoFinal;

        int[] a = new int[9999999];
        int[] b = new int[a.length];
        Random random = new Random();

        // preenchendo o array a
        for (int i = 0; i < a.length; i++) a[i] = random.nextInt();


        /*
        * TESTANDO A CÓPIA COM FOR
        * */
        tempoInicial = System.currentTimeMillis();
        for(int i = 0; i < a.length; i++) b[i] = a[i];
        tempoFinal = System.currentTimeMillis();
        System.out.println("Método 1 foi executado em: " + (tempoFinal - tempoInicial));

        /*
        * TESTANDO A CÓPIA COM System.arraycopy()
        * */
        tempoInicial = System.currentTimeMillis();
        System.arraycopy(a, 0, b, 0, a.length);
        tempoFinal = System.currentTimeMillis();
        System.out.println("Método 3 foi executado em: " + (tempoFinal - tempoInicial));

        /*
        * TESTANDO A CÓPIA COM Arrays.copyOf();
        * */
        tempoInicial = System.currentTimeMillis();
        b = Arrays.copyOf(a, a.length);
        tempoFinal = System.currentTimeMillis();
        System.out.println("Método 3 foi executado em: " + (tempoFinal - tempoInicial));


    }
}

Resultado:

Método 1 foi executado em: 10
Método 2 foi executado em: 6
Método 3 foi executado em: 19

Process finished with exit code 0
2 curtidas

Obrigado!!! Não sabia da existencia desses metodos! Eles sao nativos?
O que eu preciso fazer eh verificar se meu array existente ja esta cheio(Quando eu for entrar com mais dados) , caso estiver cheio, criar outro array e passar os dados ja existentes pra esse array novo. So q eu quero criar um método que tenha como parâmetro o tamnho do array! Assim sempre que encher , eu crio outro do tamanho desejado!
Sendo assim, existe um metodo ja existente pra isso?

São todos nativos, sim. Esse comportamento que vc descreveu é exatamente o comportamento de um ArrayList. List’s são muito mais fáceis de manipular do que um array e são nativos da API tb. Já pensou na possibilidade de conversão do tipo?

@raphaeloneves, creio que ele esteja em um caminho de aprendizado e, embora algumas coisas realmente sejam mais simples, ele precisa trilhar o caminho ladrilho a ladrilho, não concorda? Pelo que vejo, ele está aprendendo sobre alocação de memória e, provavelmente, o próximo passo sejam coleções.
Pular etapas nem sempre é uma boa ideia.

Vamos às respostas:
1- eu posso passar uma variável para ser o tamanho de uma array?
Sim;
2- Como funcionario esse return?
O método que você colocou como exemplo está errado. O tipo de retorno é apenas Funcionario quando, na verdade, precisaria ser Funcionario[] (note os colchetes indicando que o retorno é um array). E você pode chamar este método assim: Funcionario[] funcs = novaLista(5);. Esta chamada retorna um novo array com 5 posições (de 0 a 4).
3- Existe um jeito mais simples de fazer isso?
Sempre tem N maneiras de fazer a mesma coisa. Umas mais simples, outras mais complexas. Eu não sei qual o enunciado do problema a ser resolvido com o método em questão, mas, eu passaria apenas o vetor antigo e devolveria o novo, com uma posição a mais, algo como:
//Em algum lugar do método principal funcs = novaLista(funcs);
E, o método:
public Funcionario[] novaLista(Funcionario[] velhaLista){ int size = velhaLista.length + 1; Funcionario fnc[] = new Funcionario[size]; //Daqui para frente você sabe o que fazer return fnc; }

1 curtida

Muito Obrigado!
vou por em pratica tudo que vcs me ensinaram!!!