Java Vector (ve Stack) sınıfı neden kullanılmıyor veya kullanılmıyor?


677

Java Vector neden eski veya kullanılmayan eski bir sınıf olarak kabul ediliyor?

Eşzamanlılık ile çalışırken kullanımı geçerli değil mi?

Nesneleri manuel olarak senkronize etmek istemiyor ve sadece temel dizinin yeni kopyalarını yapmaya gerek kalmadan iş parçacığı için güvenli bir koleksiyon kullanmak istiyorsanız ( CopyOnWriteArrayListo zaman), o zaman kullanmak iyi Vectormi?

Peki ya Stackbir alt sınıf olan Vector, onun yerine ne kullanmalıyım?


Artık kullanılmıyorlar, ancak kullanımdan kaldırılmıyorlar.
Lorne Marquis

Yanıtlar:


655

Vectorher bir işlemde senkronize olur. Neredeyse asla yapmak istediğiniz şey bu değildir.

Genel olarak bir dizi işlemi senkronize etmek istersiniz . Tek tek işlemleri senkronize etmek hem daha az güvenlidir ( Vectorörneğin, bir yinelemeyi yinelerseniz , aynı anda başkalarının koleksiyonunu değiştirmesini önlemek için bir kilit çıkarmanız gerekir, bu ConcurrentModificationExceptionda yineleme iş parçacığında a'ya neden olur ) aynı zamanda daha yavaştır ( neden bir kez yeterli olduğunda tekrar tekrar bir kilit çıkar)?

Tabii ki, ihtiyacınız olmadığında bile kilitleme yüküne sahiptir.

Temel olarak, çoğu durumda senkronizasyon için çok kusurlu bir yaklaşımdır. As Bay Brian Henk işaret, arama kullanarak bir koleksiyon dekore edebilirsiniz gibi Collections.synchronizedList- gerçeği Vectorbirleştirir hem "her işlemi senkronize" biraz "boyutu değiştirilen dizi" koleksiyonu uygulama kötü tasarım başka bir örnektir; dekorasyon yaklaşımı endişelerin daha net ayrılmasını sağlar.

StackEşdeğer bir gelince - ile başlamak Deque/ bakmak istiyorum ArrayDeque.


108
"Genellikle bir dizi işlemi senkronize etmek istersiniz." - Mesele bu! Teşekkürler!
fjsj

7
java Deprecated Vector (şu anda Java7 kullandım) hangi sürümünde.Ancak asla Kullanım dışı olarak görmüyorum? Hoşça
kal

17
@Samir: Resmi olarak itiraz edilmiyor - sadece ArrayList genellikle tercih ediliyor.
Jon Skeet

26
@Samir: Hayır, geleceği tahmin etmeye çalışmayacağım.
Jon Skeet

5
sadece gr8. Vektör, eski bir sınıftan kaldırılmadı. Kullanımdan kaldırılan ve eski arasındaki fark olmalı ve evet, bkz. stackoverflow.com/questions/2873254/…
Prashant Shilimkar 23:13

82

Vector 1.0'ın bir parçasıydı - orijinal uygulamanın iki dezavantajı vardı:

1. Adlandırma: vektörler gerçekten sadece diziler olarak erişilebilen listelerdir, bu yüzden çağrılmış olmalıdırlar ArrayList(Java 1.2 Collections'ın yerine kullanılır Vector).

2. Eşzamanlılık: Tüm get(), set()yöntemlerdir synchronizedince senkronizasyonu üzerinde kontrolü taneli olamaz bu yüzden.

ArrayListVe arasında çok fazla fark yoktur Vector, ancak kullanmalısınız ArrayList.

API belgesinden.

Java 2 platformu v1.2'den itibaren, bu sınıf Liste arabirimini uygulamak için yeniden uyarlandı ve bu da onu Java Koleksiyonlar Çerçevesinin bir üyesi haline getirdi. Yeni koleksiyon uygulamalarının aksine, Vector senkronize edilir.


Diziler olarak erişilebilecek listeler? ArrayList çok kısa veya akılda kalıcı bir isim değildir, bu yüzden vektör başka bir yerde kullanılır (örneğin STL).
dhardy

6
@dhardy Temel uygulaması olarak bir dizi içeren liste. Orada ArrayList, LinkedListarabirimini uygulamak hepsi, vb Listsen yararlanmak isteyen eğer öyleyse, Listaslında altta yatan uygulama sadece bir alabilir ne olduğunu bilmek zorunda kalmadan yöntemleri Listaynı uygulayacaklar için de geçerlidir vb yöntemlere parametre olarak Mapve bunun gibi. Bu arada, C ++, C std::arraystili statik uzunluk dizilerinin yalnızca şablon tabanlı bir yedeği olan bir sınıfa sahiptir.
JAB

41

Vector kullanımı ile ilgili daha önce belirtilmiş cevapların yanı sıra, Vector'da numaralandırma ve eleman alımı ile ilgili Liste arayüzünden farklı bir sürü yöntem vardır ve geliştiriciler (özellikle 1.2'den önce Java'yı öğrenenler), kodu. Numaralandırmalar daha hızlı olmasına rağmen, koleksiyonun yineleme sırasında değiştirilip değiştirilmediğini kontrol etmezler, bu da sorunlara neden olabilir ve Vector'un senkronizasyon için seçilebileceği göz önüne alındığında - birden fazla iş parçacığından gelen erişim ile, bu onu özellikle zararlı bir sorun haline getirir. Bu yöntemlerin kullanımı ayrıca Vector'a birçok kodu çiftler, böylece farklı bir List uygulamasıyla değiştirilmesi kolay olmaz.


14

İş parçacığı için güvenli olmayan bir öğeden iş parçacığı için güvenli bir koleksiyon almak için, synizedCollection / List yöntemini kullanabilirsiniz java.util.Collection.


2
neden bu vektörden daha iyidir?
fjsj

8
Jon'un belirttiği gibi, Vector de performans göstermez ve bu yöntem senkronizasyonu yapmak için ne zaman iyi bir fikir olduğunu seçmenize izin verir. Tamamen bir tasarım sorunu. Senkronize olmayan erişimi varsayılan olarak kullanmanız gerektiğinden, ArrayList'i Vector üzerinden kullanmalısınız.
Brian Henk

Bu soruya nasıl cevap veriyor?
Lorne Marquis

8

java.util.Stackjava.util.Vectorgenellikle haklı olmayan senkronizasyon yükünü devralır .

Yine de bundan çok daha fazla miras alır. java.util.Stack extends java.util.VectorNesneye yönelik tasarımda bir hata olduğu gerçeği . Puristler, geleneksel olarak bir yığınla ilişkili işlemlerin ötesinde birçok yöntem sunduğunu da not edecektir (yani: itme, pop, peek, boyut). Bunu yapmak da mümkündür search, elementAt, setElementAt, remove, ve diğer birçok rasgele erişimli operasyonları. Temel olarak, yığının yığın olmayan işlemlerini kullanmaktan kaçınmak kullanıcıya kalmıştır Stack.

Bu performans ve OOP tasarım nedenlerinden ötürü, JavaDoc içinjava.util.StackArrayDeque doğal değiştirme önerilmektedir . (Deque bir yığından daha fazlasıdır, ancak en azından her şeye rastgele erişim sunmak yerine iki ucu manipüle etmekle sınırlıdır.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.