O uso de Vectores no lugar de ArrayList

Olá gente;

Alguém saberia me responder uma real necessidade ou vantagem em se utilizar Vector ao invés de List em uma aplicação?
Estou realizando manutenção em um sistema Web muito antigo. A performance dele é muito lenta…

Vlw gente…

O único caso é onde você precisa acessar simultaneamente um Vector por duas threads diferentes, e você não quer pôr um “synchronized” sobre a variável do tipo “Vector”. Mas esse caso é bastante raro em aplicações Web.

[quote=arthurgon]Olá gente;

Alguém saberia me responder uma real necessidade ou vantagem em se utilizar Vector ao invés de List em uma aplicação?
Estou realizando manutenção em um sistema Web muito antigo. A performance dele é muito lenta…

Vlw gente…[/quote]

Se o sistema é muito antigo é provável que não existisse a interface List para ele ( que só foi incluida no java 2 se não engano).

Se puder faça um refactoring de todos os retornos e declarações para List e todas as inicilaizações para Vector.
Depois descubra se ha alguma concorrência em cima dessa lista. Se não, use ArrayList.

Problemas de desempenho normalmente são:

  • Por problemas na indexação do banco de dados;
  • Por queries SQL mal-construídas;
  • Por utilização excessiva de memória da sessão;
  • Pelo uso indevido do operador “+=” com Strings para montar uma página;
  • Pelo uso de algoritmos inadequados (busca linear, ordenação com bubblesort etc.)

É um pouco difícil que trocar Vector por ArrayList vá ajudar alguma coisa. Se for usado o Java 5.0 ou superior, então devido a alguns aperfeiçoamentos no tratamento de locks, nem faria muita diferença em máquinas multiprocessadas. (Em máquina com apenas 1 processador, não faz praticamente nenhuma diferença o uso de Vector ou ArrayList).

Olá!

Os métodos de Vector podem ser sincronizados, mas para operações que utilizem mais de um método (por exemplo remover de uma posição e colocar em outra) não vai adiantar muita coisa…

//aqui ainda há o risco de inconsistencia se houver mais de uma Thread
public void trocar(){
    Object o = vetor.get(0);
    vetor.remove(o);
    vetor.add(o, 5);
}

//vai ter que ficar assim:
//que no caso não importa se fosse um Vector ou qualquer outra implementação de List
public synchronized void trocar(){
    Object o = vetor.get(0);
    vetor.remove(o);
    vetor.add(o, 5);
}

Abraços

Posso inferir dai que vc cria todos os seus programas usando Vector como implementação para List ?
Não ? Então é porque existe alguma diferença 'prática" … certo ?

Vendo por ai porque usar StringBuilder se StringBuffer faz a mesma coisa de forma thread-safe e “Em máquina com apenas 1 processador, não faz praticamente nenhuma diferença” :wink:

(não é o numero de processadores que importa, é o numero de threads concorrentes no objeto. não ?)

Uma coisa que mata não é o uso de Vector ou ArrayList.

É que as pessoas não sabem que existem outras estruturas de dados como Set ou Map; e quando vão fazer buscas elas sempre usam busca linear sobre um Vector ou ArrayList.

Pior de tudo, já vi muita gente boa que, para fazer uma busca linear, em vez de abandonar o “for” quando encontram o dado, acabam continuando a percorrer a lista :frowning:

Em seu blog, o Cliff Click (da Azul Systems) comenta o caso em que ele teve de efetuar uma análise de desempenho (do tipo “eu comprei uma máquina com 1024 processadores Java e o programa roda muito lentamente, a culpa é de quem?”). Obviamente ele teve de:

  • Descompilar o programa do cliente, que tinha uma busca linear desse tipo (o cliente não se dignou nem a fornecer o código-fonte…)
  • Recompilar o programa usando uma estrutura de dados mais decente;
  • Medir os resultados, que foram estupidamente mais rápidos.

Um dia na faculdade, meu professor me mostrou um outro método de busca…

Não é busca sequencial…é um outro que eu não me recordo…

Disse ele que o programa fica com um rendimento de 80% melhor que busca sequencial…

Não me recordo como é…mas eu sei que vc ordena o vetor ou a lista e vai dividindo por 2…

Se uma pessoa escolher um numero de 0 a 1000, em 10 perguntas, no pior caso, ele descobre qual é o numero.

Em busca sequencial, ele faria, no pior caso, 1000 perguntas.

Uma boa diferença!

Essa busca dividida por 2 chama-se busca binária :lol:

[quote=thingol]Uma coisa que mata não é o uso de Vector ou ArrayList.

É que as pessoas não sabem que existem outras estruturas de dados como Set ou Map; e quando vão fazer buscas elas sempre usam busca linear sobre um Vector ou ArrayList.
[/quote]

A tá, ok, mas o problema não era a busca e sim usar uma ou outra implementação. É claro que poderíamos usar LinkedList ou o CopyOnWriteArrayList mas o ponto era substituir Vector sem alterar a interface. Para usar um Set ou Map teriamos que alterar
o sistema ainda mais profundamente porque as interfaces são diferentes. (se bem que é verdade que a grande maioria de returns pode ser mudado para Collection).

O que me estranhou foi vc dizer que não ha nenhum efeito em trocar um pelo outro.

Boaaaaaa…

É verdadeeee…

Hahaha…que idiota que eu sou! Dividindo por 2 só poderia ser binária!

aUIhAIUahiuaHiuaHuiahaiuaIUhA

Me rebaixei a Smalltalk depois dessa!

A busca binária (onde se supõe que os elementos estejam ordenados) tem tempo de execução proporcional ao logaritmo de N, onde N é o número de elementos. Mas se os elementos estiverem em uma “hash table” (tabela de índice calculado), esse tempo de execução é praticamente fixo.

Hum… pela minha experiência, normalmente problemas de desempenho nunca são tão fáceis de resolver que você simplesmente troque a implementação sem mudar a interface. Há certas coisas que precisam de cirurgias mais radicais.

Vector ou ArrayList?

Vector é uma das piores e mais horrorosas classes que já foram inventadas no java. Faça-se o favor de esquecer que ela existe e abominá-la e odiá-la bem como a todos que insistem em utilizá-la, para que ela possa ser atirada no enxofre das profundezas do submundo e perecer por toda a eternidade no castigo que essa infortúnia classe merece.

Eliminando Vector, chegamos ao ponto onde pensa-se que ArrayList é a solução para tudo, algo que é uma grande mentira. O correto é usar List (“CODE TO AN INTERFACE”). Você só usa ArrayList se:

Você está instanciando a lista AND (você precisa acessar a lista em posições não lineares OR você já sabe o tamanho máximo que a lista vai ter quando a criar) AND (você não vai inserir e nem excluir elementos em uma posição que não seja a última OR a lista é pequena).

Considere também usar LinkedList se:
Você está instanciando a lista AND (você SEMPRE vai percorrer a lista linearmente OR você vai percorre-la de trás-para-frente) AND (se você quiser, você vai inserir ou excluir elementos no meio ou no começo da lista).

Se você não estiver instanciando nada, use apenas List (repetindo: code to an interface!)

Vale lembrar que ArrayList e LinkedList não são thread-safe. Se você precisa de segurança a threads, considere usar o seguinte método:

public static <E> java.util.List<E> java.util.Collections.synchronizedList(java.util.List<E> list);

Assim, segurança em threads não é desculpa para usar Vector no lugar de ArrayList. E se você tem requisitos de concorrência bem peculiares, as implementações de List no pacote java.util.concurrent também podem te ajudar.

E se você não ficar satisfeito com nenhuma destas implementações, porque não criar a sua própria classe que implemente java.util.List?

Por fim, nem tudo são Lists. Pesquise java.util.Map, java.util.Set, java.util.Collection, java.util.Iterator e java.lang.Iterable bem como as suas diferentes implementações.