[RESOLVIDO] O que significa <> após o nome da classe?

Boa noite. Desculpe se estou postando no local errado, mas sou novato. Bom, a dúvida é a seguinte: estou aprendendo estrutura de dados e fui apresentado a seguinte nomenclatura de classe que nunca havia visto antes:

public class nomeDaClasse <Key, Value> { … }

Eu gostaria de saber o que é que significa essa parte: <Key, Value>.

Significa que a classe é uma classe genérica. Eis um tutorial bem legal sobre o assunto:

https://docs.oracle.com/javase/tutorial/extra/generics/intro.html

Provavelmente no interior da sua classe vc terá algum código assim:

public class MyGenericClass<Key, Value> {
    Key k;
    Value v;
}

As variáveis k e v são atributos normais da classe, mas seu tipo pode mudar dependendo de como a classe foi instanciada. Se eu fizer assim:

new MyGenericClass<String, Integer>();

Os tipos dos atributos k e v serão, respetivamente, String e Integer.

Generics são especialmente úteis quando se trabalha com coleções, estruturas de dados que contém vários elementos de um certo tipo.

Imagine que vc vai criar um ArrayList não-genérico. Você teria algo assim:

public class ArrayList {
    int[] elements;

    public void add(int element) { /* ... */ }

    public int get(int index) { /* ... */ }

    /* ... */
}

Ou pelo menos assim:

public class ArrayList {
    Object[] elements;

    public void add(Object element) { /* ... */ }

    public Object get(int index) { /* ... */ }

    /* ... */
}

Basicamente, no primeiro exemplo, você poderia inserir neste ArrayList apenas objetos do tipo int o que torna esta estrutura pouco flexível e bastante limitada.

Já no segundo exemplo vc poderia inserir objetos de qualquer tipo, mas vc seria obrigado a usar casts por todos seu código.

ArrayList list = new ArrayList();
list.add("Uma string qualquer");
String s = (String) list.get(0);

Fora que seria fácil inserir objetos de tipos variados, o que poderia causar situações desagradáveis.

list.add("String");
list.add(123);
list.add(new int[9999]);

Mas com generics é possível inserir objetos de qualquer tipo, só que de forma segura e checada pelo compilador. Reformulado, nosso ArrayList ficaria mais ou menos assim:

public class ArrayList<T> {
    T[] elements;

    public void add(T element) { /* ... */ }

    /* ... */
}

Agora eu poderia criar um ArrayList de Strings com:

ArrayList<String> list = new ArrayList<String>();

De números inteiros:

ArrayList<Integer> list = new ArrayList<Integer>();

Ou qualquer outro tipo que eu queira.

Fiz um código pra mostrar. Ficou assim:

Note que usei um Object[] ao invés de T[].

class ArrayList<T> {
    Object[] elements;
    private int capacity;
    private int index = 0;

    public ArrayList(int capacity) {
        elements = new Object[capacity];
        this.capacity = capacity;
    }

    public void add(T element) {
        if ( index < capacity ) {
            elements[ index ] = element;
            index++;
        } else throw new RuntimeException("ArrayList Cheio!!!");
    }

    public T get(int index) {
        if ( index < this.index ) {
            return (T) elements[index];
        } else throw new RuntimeException("Index fora dos limites!!!");
    }
}

class Program {
    public static void main(String... args) {
        ArrayList<String> list = new ArrayList<String>(1);
        list.add("teste");
        System.out.println(list.get(0));
    }
}

No exemplo acima, tente algo como:

list.add(123);

E o compilador lhe avisará do erro: Inteiros não podem ser convertido para String!

Testa aí e veja se a explicação lhe ajuda.

6 curtidas

Muito obrigado pela resposta extremamente detalhada! Me ajudou muito a entender!

1 curtida