A Certificação SCJP (Sun Certified Java Programmer) vem se tornando cada vez mais um diferencial no mercado de trabalho, apesar de gerar muita discussão, é inquestionável que tem seu valor. Então iniciaremos uma série de onze artigos denominada “Desmistificando a Certificação SCJP6”. Na ordem trataremos os seguintes assuntos: Conjuntos, Genéricos, Classes Internas e Datas, Conceitos Essenciais, Multithreading, Orientação a Objetos, Atribuições, Operadores, Exceções e Assertivas, Strings, E/S e Serialização, Regexps e Compilação. Trataremos os assuntos de forma bem objetiva e, no fim de cada artigo, apresentaremos algumas questões sobre assuntos tratados no mesmo, como um simulado para a prova. Iniciaremos essa série falando de Conjuntos.

Os conjuntos devem realizar operações de inserção, remoção, pesquisa, busca, recuperação e iteração de objetos. É essencial saber inicialmente que existem diversos tipos de conjuntos, cada qual com um propósito específico, no entanto, a proposta do exame para esse tópico não é que você domine todos os conceitos de estruturas de dados, e sim compreenda o básico do funcionamento dos conjuntos.

List (Interface)
As classes que a implementam apresentam o índice; com isso pode-se adicionar um item no meio da lista. Como você já deve ter percebido, as classes que implementam a interface List são ordenadas por meio de um índice, o que proporciona o acesso a qualquer elemento por meio desse índice.
ArrayList (Implementa List - Acesso aleatório e iteração rápidos)
Um ArrayList é um array que é capaz ser alterado. A estrutura interna é baseada em um Array, com um tamanho inicial que deve ser declarado na criação do objeto. O valor default, no caso de não definição, é 10. Características principais de um ArrayList:
  • Devido ao índice, a operação de acesso a um elemento no meio da lista é extremamente rápida, é equivalente a recuperar um item de um vetor;
  • Acesso aleatório/sequencial extremamente rápido;
  • Assim como o acesso, a inserção é extremamente rápida;
  • Um ArrayList cresce à medida que os itens são inseridos.
Ex.: ArrayList <Integer> myArrayList = new ArrayList <Integer>();
Vector (Implementa List)
Tal qual um ArrayList, só que relativamente mais lento, devido aos seus métodos sincronizados. Um Vector possui as mesmas características de um ArrayList, no entanto, seus métodos são sincronizados.
Ex.: Vector <Integer> myVector = new Vector <Integer>();
LinkedList (Implementa Queue)
Apropriado para inserção de elementos no seu final, ou seja, ideal para pilhas e filas. Um conjunto LinkedList pode ser mais lento do que ArrayList no que diz respeito à iteração, porém será uma boa opção para inserções e exclusões rápidas. O importante é saber que o índice em uma lista é relevante.
Ex.: LinkedList <Integer> myLinkedList = new LinkedList <Integer>();
Set (Interface)
O que é imprescindível saber sobre a interface Set é que as classes que a implementam não aceitam duplicatas (elementos repetidos). Esse conceito é fundamental para o entendimento das classes que implementam a interface Set.
HashSet (Implementa Set)
Garante a não existência de duplicatas e não fornece ordenamento. HashSet é um conjunto não-classificado e não ordenado que utiliza o código hash do elemento que está sendo inserido na lista para saber em qual depósito o elemento deve ser armazenado.
Ex.: HashSet <Integer> myHashSet = new HashSet <Integer>();
LinkedHashSet (Implementa Set)
Itera por ordem de inserção e sem duplicatas. Ideal em caso de necessidade de ordem na iteração. Pode ser mais lenta que HashSet na inserção, pois leva mais tempo para registrar os vizinhos, ou seja, elemento posterior e anterior.
Ex.: LinkedHashSet <Integer> myLinkedHashSet = new LinkedHashSet();
TreeSet (Implementa Set)
Itera por ordem classificada e sem duplicatas. TreeSet é uma das classes da API de coleção Java que é ordenada e classificada. Essa classificação acontece pela ordem natural da classe que está sendo inserida, o que pode ser modificao.
Ex.: TreeSet <Integer> myTreeSet = new TreeSet <Integer>();

Classificando Conjuntos e Arrays

Qualquer ArrayList pode ser classificado. Assim como um TreeSet pode ser classificado por meio da ordem natural de seus elementos, os ArrayLists também podem ser classificados da mesma maneira.


        import java.util.*;
        public class Classificacao{
        public static void main (String args[]){
        List lista1 = new ArrayList();
        lista1.add(new Integer(9));
        lista1.add(new Integer(8));
        lista1.add(new Integer(10));
        lista1.add(new Integer(6)+3);
        lista1.add(7);
        System.out.println(lista1);

        Collections.sort(lista1);

        System.out.println(lista1);

        }

        }
        Saída:
        [9,8,10,9,7]
        [7,8,9,9,10]
        

Conversão array para ArrayList e ArrayList para Array

Classes que implementam as interfaces Set e List possuem disponíveis o método toArray(). Em contrapartida a classe Arrays tem o método asList(). Um método faz, obviamente, o contrário do outro. A necessidade de utilização do método asList() é maior do que a de usar o toArray(), pois um conjunto oferece uma maior quantidade de possibilidades do que um array.


        import java.util.*;

        class Pessoa{
        String name;
        int age;
        Pessoa(String name, int age){
        this.name = name;
        this.age = age;
        }

        public String toString(){

        return name+” ”+age;

        }

        }
        public class Test{
        public static void main(String args[]){
        Pessoa p1 = new Pessoa(“Java”, 15);
        Pessoa p2 = new Pessoa(“SCJP”, 6);
        Pessoa [] p = {p1,p2};
        List ar = Arrays.asList(p);
        System.out.println(ar);
        ar.set(0, new Pessoa(“Davi”, 26));
        System.out.println(ar);
        Object [] conversao = ar.toArray();
        for(Object obj: conversao){
        System.out.print((Pessoa) obj +” “);
        }
        }
        }
        

Saída: [Java 15, SCJP 6]
[Davi 26, SCJP 6]
Davi 26 SCJP 6

Interface Map
Os métodos hashCode() e equals() devem ser sobrescritos por todas as classes que implementarem a interface Map. No entanto, isso não é obrigatório, porém o fato desses métodos não serem sobrescritos inutilizará completamente o Map.
HashMap (Implementa Map)
É um Map que disponibiliza, além de atualizações mais eficientes (rápidas), a inserção de chaves e valores nulos.
Ex.: HashMap <String, Integer> myHashMap = new HashMap <String, Integer>();
HashTable (Implementa Map)
Comportamento bastante semelhante ao do HashMap. Difere no fato de seus métodos serem sincronizados, apresentando, portanto, operações mais lentas. HashTable não permite valores nulos nem para chave, nem para o valor.
Ex.: HashTable <String, Integer> myHashTable = new HashTable <String, Integer>();
TreeMap
É um mapa classificado. Essas classes sobrescrevem todos os métodos necessários para que as duplicidades não ocorram(equals() e hashCode()) e implementam a interface Comparable, possibilitando que a lista saia ordenada.
Ex.: Map myTreeMap = new TreeMap();
PriorityQueue (Implementa Queue)
Tendo a classe LinkedList sido aprimorada para implementar a interface Queue, as filas básicas podem ser manipuladas com uma LinkedList. A PriorityQueue tem como propósito criar uma fila com ordenamento “prioridade de entrada-prioridade de saída” LIFO (Last In First Out), ao invés do sistema FIFO (First In First Out). Os elementos de PriorityQueue são ordenados de forma natural ou de acordo com um Comparator.

Pesquisando TreeMaps e TreeSets

Duas novas interfaces que foram introduzidas na versão 6 do Java são cobradas no novo exame, são elas: java.util.NavigableMap e java.util.NavigableSet.


        import java.util.*;
        public class Embarcacao{
        public static void main (String args[]){
        TreeSet<Integer> horas = new TreeSet<Integer>();
        horas.add(1000);
        horas.add(1503);
        horas.add(1453);
        horas.add(2020);
        horas.add(2012);
        System.out.println(“Última antes das 16:00: ”+ horas.lower(1600));
        System.out.println(“Primeira depois das 20:00: ”+ horas.higher(2000));
        }

        }
        

Saída:
Última antes das 16:00: 1503
Primeira depois das 20:00: 2012

Mini-teste.

  1. Analise o seguinte trecho de código:

    
                    package sersoft1;
                    public class X{
                    int a;
                    String b;
                    X(int a, String b){
                    this.a=a;
                    this.b=b;
                    }
                    public boolean equals(Object o){
                    if((o instanceof a)&&(((a)o)).b.equals(this.b))
                    return true;
                    else
                    return false;
                    }
                    public static void main(String args[ ]){
                    X x = new X(10, “Java”);
                    X y = new X(20, new String(“Java”));
                    X z = new X(10, “java”);
                    System.out.print(x.equals(y));
                    System.out.print(x.equals(z));
                    System.out.print(y.equals(z));
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. truefalsefalse
    2. truetruefalse
    3. falsefalsefalse
    4. falsefalsetrue
  2. Assumindo que os métodos equals() e hashCode() foram corretamente sobrescritos, assinale as alternativas verdadeiras:

    1. Se o operador == de comparação de hashCode() retornar true, o método equals() pode retornar true.
    2. Se o operador == de comparação de hashCode() retornar true, o método equals() deve retornar true.
    3. Se o método equals() retornar false, o operador == de comparação de hashCode() pode retornar true.
    4. Se o método equals() retornar true, o operador == de comparação de hashCode() pode retornar true.
    5. Se o método equals() retornar true, o operador == de comparação de hashCode() deve retornar true.
    6. Se o operador != de comparação de hashCode() retornar true, o método equals() pode retornar true.
  3. Analise o seguinte trecho de código:

    
                    package sersoft1;
                    import java.util.*;
                    public class A{
                    Integer i;
                    A(Integer i){
                    this.i=i;
                    }
                    public boolean equals(Object o){
                    if(((A)o).i==this.i)
                    return true;
                    else
                    return false;
                    }
                    public int hashCode(){
                    return i^13;
                    }
                    public static void main(String args[ ]){
                    Set s = new LinkedHashSet();
                    s.add(11);
                    s.add(8);
                    s.add(11);
                    s.add(21);
                    s.add(8);
                    System.out.println(s);
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. 8 11 21
    2. 11 8 11 21 8
    3. 11 8 21
    4. Ordem de saída imprevisível.
  4. Analise o seguinte trecho de código:

    
                    package sersoft1;
                    import java.util.*;
                    public class A{
                    Integer i;
                    A(Integer i){
                    this.i=i;
                    }
                    public boolean equals(Object o){
                    if(((A)o).i==this.i)
                    return true;
                    else
                    return false;
                    }
                    public int hashCode(){
                    return i^13;
                    }
                    public static void main(String args[ ]){
                    List s = new LinkedList();
                    s.add(11);
                    s.add(8);
                    s.add(1, 15);
                    s.add(21);
                    s.add(8);
                    System.out.println(s);
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. 11 8 15 21
    2. 11 15 8 21 8
    3. 15 11 8 21
    4. 11 8 15 21 8
    5. Ordem de saída imprevisível.
  5. Analise o seguinte trecho de código:

    
                    package sersoft2;
                    import.java.util.*
                    public class Automovel{
                    public static void main(String args[ ]){
                    int [ ] lista = {1, 5, 3, 6, 0};
                    System.out.println(“Índice: “ + Arrays.binarySearch(lista, 5));
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. 0
    2. 1
    3. 2
    4. O código apresentará erro de compilação.
    5. Será lançada uma exceção.
    6. Uma chamada ao método binarySearch() só tem sentido para arrays ordenados.
  6. Qual faixa de resultados poderia ser produzida por uma chamada correta de Arrays.binarySearch() em um array String devidamente preparado contendo 6 elementos?

    1. 0 a 6
    2. 0 a 5
    3. -1 a 6
    4. -1 a 5
    5. -6 a 5
    6. -7 a 5
  7. Analise o seguinte trecho de código:

    
                    public class TesteArrayList{
                    public static void main(String args[ ]){
                    List l = new ArrayList();
                    l.add(0);
                    l.add(2);
                    l.add(4);
                    Object [ ] convertido = l.toArray();
                    convertido[0] = new Integer(100);
                    System.out.println(l);
                    
    1. 100 2 4
    2. 0 2 4
    3. Ordem de saída imprevisível.
    4. A conversão de um List em um array não é possível.
  8. Para funcionarem de forma correta, quais classes devem sobrescrever os métodos equals() e hashCode()?

    1. java.util.Map
    2. java.util.TreeMap
    3. java.util.HashMap
    4. java.util.LinkedHashMap
    5. java.util.TreeSet
  9. Determinada classe de conjunto permite que você aumente ou diminua o seu tamanho e fornece acesso indexado aos seus elementos, porém, não possui métodos sincronizados. Essa classe é:

    1. java.util.Set
    2. java.util.HashSet
    3. java.util.List
    4. java.util.ArrayList
    5. java.util.HashMap
    6. java.util.Vector

Gabarito comentado

  1. Resposta correta: A

    O método equals() está devidamente sobrescrito. A igualdade entre objetos implica em que eles sejam significativamente equivalentes, duas instâncias X são iguais se o atributo String for o mesmo. Cuidado, pois podemos acreditar que duas instâncias X somente serão equivalentes se todos os seus atributos tiverem os mesmos estados.
  2. Resposta correta: A, C e E

    Em cenários de sobrescrição válidos de hashCode() e equals(), o método equals() retornará true somente quando o operador de comparação == de hashCode() retornar true. Em uma situação contrária, quando o operador de comparação == de hashCode() retornar false, o método equals() nunca retornará true. Então, se o operador == de comparação de hashCode() retornar true, o método equals() pode retornar true(alternativa A). Se o método equals() retornar false, o operador == de comparação de hashCode() pode retornar true(alternativa C). Se o método equals() retornar true, o operador == de comparação de hashCode() deve retornar true(alternativa E).
  3. Resposta correta: C

    Um LinkedHashSet é ordenado de acordo com a inserção. Trata-se de uma lista duplamente encadeada. Quando os métodos equals() e hashCode() são sobrescritos de forma correta, o LinkedHashSet elimina duplicidades.
  4. Resposta correta: B

    Conjuntos que implementam List são ordenados pelo índice. Estes conjuntos não fazem restrições com relação à duplicidade de elementos. O método add() é sobrecarregado para que possa passar um índice. Ao passar um índice, a ordem é alterada, pois um elemento foi inserido em uma estrutura já existente.
  5. Resposta correta: F

    Como estamos tratando de busca e ordenação envolvendo arrays, percebe-se que o array não está ordenado e é invocado o método binarySearch().
  6. Resposta correta: F

    Se o array possui seis elementos, o índice do último elemento é 5. O próximo elemento seria o de índice 6. Como esse elemento não existe, o método binarySearch() retorna -7, pois -(-7+1) resulta em 6, que seria a posição de entrada. Portanto, a faixa de valores possível para um array classificado de 6 elementos vai de -7 a 5.
  7. Resposta correta: B

    O método toArray() tem a capacidade de transformar um List em um array. Porém, a partir da conversão, o array e o List estão totamente descompatibilizados. Assim, uma alteração no array não afeta o List, e vice-versa.
  8. Resposta correta: B, C e D

    As classes que implementarem a interface Map devem sobrescrever os métodos equals() e hashCode(). HashMap, LinkedHashMap e TreeMap pertencentem ao pacote java.util. É importante lembrar que Map é uma interface e que TreeSet é um Set.
  9. Resposta correta: D

    Set e List são interfaces. Interfaces não podem ser confundidas com classes. A classe que vai ao encontro dos objetivos é ArrayList.

Leia todos artigos da série