Кіріспе
Java-дағы коллекциялар
Java коллекциялар фреймворкі – жиі қайта қолданылатын коллекция дерек құрылымдарын іске асыратын сыныптар мен интерфейстер жиынтығы. Фреймворк деп аталғанымен, ол кітапхана сияқты жұмыс істейді. Коллекциялар фреймворкі әртүрлі коллекцияларды анықтайтын интерфейстерді және оларды іске асыратын сыныптарды қамтиды.
Массивтерден айырмашылықтары
Жинақтар мен массивтер ұқсас, өйткені екеуі де объектілерге сілтеме жасайды және оларды топ ретінде басқаруға болады. Дегенмен, массивтерден айырмашылығы, жинақтарды инстанция жасағанда белгілі бір сыйымдылыққа бекіту қажет емес. Жинақтар нысандар қосылғанда немесе алынып тасталғанда автоматты түрде көлемін өсіре де, азайта да алады. Жинақтар int, long немесе double сияқты бастапқы дерек түрлерін сақтамайды. Оның орнына, жинақтар , , немесе сақтай алады. Жинақтар жалпыланған (generic) және сондықтан өзгермейтін (invariant), ал массивтер ковариантты болып табылады. Бұл, мысалы, массивтермен салыстырғанда жалпыланған нысандардың артықшылығы болып саналады, себебі жағдайларға байланысты, массивтің орнына жалпыланған нысанды қолдану, кодты түзету қажеттігі туралы дамытушыға хабарлап, компиляция уақытында қате шығару арқылы орындалу уақытындағы қателердің алдын алады. Мысалы, егер дамытушы объектіні жариялап, оған белгілі бір сыйымдылығы бар жаңа инстанция қайтарған мәнді тағайындаса, компиляция уақытында қате шығарылмайды. Егер дамытушы осы объектіге қосуға тырысса, Java бағдарламасы қате шығарады. Ал егер дамытушы жаңа инстанциясын деп жарияласа, Java компиляторы (дұрыс) кодтың үйлесімсіз және дұрыс емес типпен жазылғандығын көрсету үшін компиляция уақытында қате шығарады, осылайша кез келген орындалу уақытындағы қателердің алдын алады. Дамытушы кодты объект ретінде инстанциялау арқылы түзетуге болады. Егер код Java SE7 немесе одан кейінгі нұсқаларын қолданса, дамытушы алмаз операторын пайдаланып объект ретінде инстанциялай алады. Жинақтар жалпыланған және сондықтан нақтыланған (reified), ал массивтер нақтыланбаған.
Collections are generic and hence invariant, but arrays are covariant. This can be considered an advantage of generic objects such as when compared to arrays, because under circumstances, using the generic instead of an array prevents run time exceptions by instead throwing a compile time exception to inform the developer to fix the code. For example, if a developer declares an object, and assigns the object to the value returned by a new instance with a certain capacity, no compile time exception will be thrown. If the developer attempts to add a to this object, the java program will throw an On the other hand, if the developer instead declared a new instance of a as , the Java compiler will (correctly) throw a compile time exception to indicate that the code is written with incompatible and incorrect type, thus preventing any potential run time exceptions. The developer can fix the code by instantianting as an object. If the code is using Java SE7 or later versions, the developer can instatiate as an object by using the diamond operator
Collections are generic and hence reified, but arrays are not reified.
Тарих
Java платформасының JDK 1.2 нұсқасына дейінгі жинақтарды іске асыру бірнеше дерек құрылымдары сыныптарын қамтыды, бірақ жинақтар аясын қамтымады. Java нысандарын топтастырудың стандартты тәсілдері массив, Vector және Hashtable сыныптары арқылы жүзеге асырылды, алайда оларды кеңейту қиын болды және стандартты мүше интерфейсін іске асырмады. Қайта пайдалануға болатын жинақ дерек құрылымдарының қажеттілігін қанағаттандыру үшін бірнеше тәуелсіз аялар және ObjectSpace Generic Collection Library (JGL) әзірленді, олардың басты мақсаты C++ Standard Template Library (STL) -мен үйлесімділік болды. Жинақтар аясын негізінен Джошуа Блох жобалады және ол JDK 1.2 нұсқасында енгізілді. Ол Дуг Лидің Collections жинағынан көптеген идеялар мен сыныптарды пайдаланды, осының нәтижесінде ол қолданыстан шығарылды. Кейін Дуг Ли Collection-мен байланысты жаңа сыныптарды қамтитын параллелизм пакетін жасады. Осы параллелизм құралдарының жаңартылған нұсқасы JSR 166 стандарты бойынша JDK 5.0 нұсқасына қосылды.
Сәулет
Java-дағы барлық дерлік жинақтар интерфейстен туындайды. Жинақ барлық жинақтардың негізгі бөліктерін анықтайды. Интерфейс жинаққа элемент қосу үшін және одан алып тастау үшін сәйкесінше `add()` және `remove()` әдістерін қамтиды. Сондай-ақ, ол жинақтағы нысандар массивіне жинақты түрлендіретін `toArray()` әдісіне ие (қайтарым түрі `Object[]`). Соңында, `contains()` әдісі белгілі бір элементтің жинақта бар-жоғын тексереді. Жинақ интерфейсі `Iterable` интерфейсінің қосалқы интерфейсі болып табылады, сондықтан кез келген жинақ `for each` операторының нысаны бола алады. (`Iterable` интерфейсі `for each` операторларымен қолданылатын `iterator()` әдісін ұсынады.) Барлық жинақтарда жинақтағы барлық элементтерді аралап өтетін итератор болады. Жинақ – типтелген. Кез келген жинақ кез келген типтегі нысандарды сақтай алады. Мысалы, кез келген `Collection` интерфейсінің іске асырылуы `Object` нысандарын қамтиды. `Collection<String>` интерфейсінің іске асырылуынан алынған нысандарды пайдаланғанда типке келтіру қажет емес. Бұрышты жақшалар `<>` жинақтың қандай типтегі мәліметтерді сақтайтынын көрсететін типтік аргументті ұстай алады.
method checks if a specified element exists in the Collection. The Collection interface is a subinterface of , so any Collection may be the target of a for each statement. (The Iterable interface provides the method used by for each statements.) All Collections have an that goes through all of the elements in the Collection. Collection is generic. Any Collection can store any For example, any implementation of contains objects. No casting is required when using the objects from an implementation of Collection<String>. Note that the angled brackets can hold a type argument that specifies which type the Collection holds.
Жинақтау түрлері
Жинақтың бірнеше жалпы түрлері бар: кезектер, карталар, тізімдер және жиынтықтар. Кезектер бағдарламашыға элементтерді белгілі бір ретпен қоюға және сол элементтерді дәл сол ретпен алуға мүмкіндік береді. Мысалы, күту тізімі. Кезектерге арналған негізгі интерфейстер Кезек деп аталады. Карталар/Сөздіктер нысандарға сілтемелерді іздеу кілті арқылы сақтайды, осы кілт арқылы нысанның мәндеріне қол жеткізуге болады. Кілттің мысалы – жеке куәлік. Карталар/Сөздіктерге арналған негізгі интерфейс Map деп аталады. Тізімдер – бір мәнді бірнеше рет сақтауға болатын шектеулі жиынтықтар. Жиынтықтар – ретсіз жиынтықтар, оларды қарап шығуға болады және әрбір элементті бір рет ғана қамтиды. Жиынтықтарға арналған негізгі интерфейс Set деп аталады.
Вектор класы
Сабақтың тікелей кіші класы ретінде қарастырылады. Бұл Java платформасы кітапханаларында композицияны мұрагерлікке басымдық беру қағидасын бұзудың мысалы, себебі компьютерлік ғылымда вектор, әдетте, стек болып табылмайды. Осы жағдайда композиция қолдану тиімдірек болар еді.
Стейк класы
Stack класы векторды стек ретінде қарауға мүмкіндік беретін бес операциямен класты кеңейтеді. Стектер жаңа нысанды стекке қою (әдіс) және стекке нысандарды алу (әдіс) арқылы құрылады. Стек соңғы кірген, бірінші шықты (LIFO) принципі бойынша нысанды қайтарады, яғни стекке соңғы қойылған нысан бірінші болып алынады. java.util.Stack – Java-да ұсынылған стектердің стандартты іске асырылуы. Stack класы нысандардың соңғы кірген, бірінші шықты (LIFO) стегін көрсетеді. Stack класы векторды стек ретінде қарауға мүмкіндік беретін бес қосымша операцияға ие. Кәдімгі және операциялармен қатар, стектегі жоғарғы элементті қарауға арналған әдіс, стек бос екенін тексеру әдісі және стекте элементті іздеу және оның жоғарғы жағынан қаншалықты алыс екенін анықтау әдісі де ұсынылады. Стек алғаш құрылғанда, онда ешқандай элемент болмайды.
CopyOnWriteArrayList класы
The класты кеңейтеді, бірақ басқа кластарды кеңейтпейді. артық синхрондауды қолданбай, жіп қауіпсіздігін қамтамасыз етеді. Кейбір жағдайларда синхрондау қажет. Мысалы, егер әдіс статикалық өрісті өзгертетін болса, және сол әдіс бірнеше жіптерден шақырылатын болса, онда синхрондау міндетті, ал бір мезгілде жұмыс істеу құралдарын қолдануға болмайды. Дегенмен, синхрондау өнімділікке кедергі келтіруі мүмкін. Синхрондау қажет емес жағдайларда, көп ядролы процессорларды пайдаланып, CPU-дың тиімді пайдаланылуын қамтамасыз ететін, жіп қауіпсіз және синхрондауға қолдайтын балама болып табылады.
Кезек интерфейстері
Интерфейс элементтерді енгізілген ретімен сақтайтын кезек дерек құрылымын анықтайды. Жаңа қосымшалар саптың соңына қойылады, ал элементтер басынан алынып тасталады. Бұл бірінші кірген, бірінші шыққан (FIFO) жүйесін құрайды. Бұл интерфейс java.util.LinkedList және басқа да сыныптар арқылы іске асырылады.
Басымдық кезегі класы
Жаваның `util.PriorityQueue` класы `java.util.Queue` интерфейсін іске асырады, бірақ оны өзгертеді. `PriorityQueue`-да қосымша әдіс бар. Элементтер енгізілген ретімен емес, басымдық бойынша реттеледі. Басымдықты анықтау үшін қолданылатын әдіс, элементтердің өзіндегі әдіс немесе конструкторда көрсетілген әдіс болып табылады. Бұл класс элементтерді сұрыптап ұстау үшін үйінді (heap) құрылымын пайдаланады.
Бір уақытта байланысқан кезек класы
Жаваның `util.concurrent` пакетіндегі `ConcurrentLinkedQueue` класы `ConcurrentLinkedQueue` интерфейсін іске асырады. `ConcurrentLinkedQueue` класы - бұл салымдар бойынша қауіпсіз жиынтық, себебі кез келген элемент жиынтыққа қойылғанда, Java Collection Library элементтің қауіпсіз жариялануын кепілдіктейді, кез келген жіпке жиынтықтан осы элементті алуға мүмкіндік беру арқылы. Объект қауіпсіз жарияланды деп есептеледі, егер объектінің күйі басқа барлық жіптерге бір уақытта көрінетін болса. Қауіпсіз жариялау көбінесе жариялаушы және тұтынушы жіптердің синхрондалуын қажет етеді.
LinkedList класы
LinkedList, әрине, List интерфейсін де іске асырады және оны да пайдалануға болады. Бірақ оған Queue әдістері де кіреді. LinkedList интерфейсін іске асырады, бұл оған көбірек икемділік сыйлайды.
ArrayDeque класы
ArrayDeque кезекті массив ретінде іске асырады. LinkedList сияқты, ArrayDeque де интерфейсті іске асырады.
Интерфейстерді орнату
Java интерфейсі Set-ті анықтайды. Set-те ешқандай қайталама элементтер болмауы тиіс. Сонымен қатар, Set-тің белгілі бір реті жоқ. Осылайша, элементтерді индекс бойынша табу мүмкін емес. Set , , және арқылы жүзеге асырылады.
Интерфейс орындалуларын орнату
Set интерфейсінің бірнеше іске асырылуы бар, оның ішінде оның кіші кластары және соңғы статикалық ішкі класы (мұндағы және формалды типтік параметрлер).
Абстрактты жинақ
интерфейс үшін қаңқалық реализация болып табылады. , , және -нің тікелей туынды кластары болып табылады.
EnumSet класы
Сынып кеңейтіледі. Сыныптың қоғамдық конструкторлары жоқ, тек статикалық фабрикалық әдістері бар. Сыныпта статикалық фабрикалық әдіс бар. Бұл әдіс агрегациялық әдіс болып табылады. Ол бірнеше параметрлерді қабылдайды, параметрлердің типін ескереді, содан кейін тиісті типтегі экземплярды қайтарады. 2018 жылдан бастап Java SE8 OpenJDK іске асылымында клиентке көрінбейтін екі іске асыру қолданылады, олар — және . Егер кішкентай enum типтері үшін ешқандай өнімділік артықшылығы болмаса, Java жинағы кітапханасына кері әсер етпей, кітапханадан алынып тастауға болады. Бұл биттік өрістердің жақсы орнына жатады, олар жиынтық типі болып табылады. Дәстүрлі түрде, әзірлеушілер жинаққа қою қажет болған санамаланған тип элементтерімен кездескенде, әр тұрақтыға 2-нің әртүрлі дәрежесін тағайындаған int enum үлгісін қолданды. Бұл биттік бейнелеу әзірлеушіге биттік ЖӘНЕ (OR) операциясын қолдануға мүмкіндік береді, сондықтан тұрақтыларды жинаққа біріктіруге болады, бұл биттік өріс деп те аталады. Бұл биттік өріс бейнелеуі әзірлеушіге тиімді жинақ операцияларын және қиылыс, біріктіру сияқты биттік арифметиканы жасауға мүмкіндік береді. Дегенмен, биттік өріс бейнелеу тәсілімен көптеген мәселелер бар. Биттік өріс int enum тұрақтысынан қарағанда аз оқылғыш. Сондай-ақ, егер элементтер биттік өрістермен бейнеленген болса, осы элементтердің барлығын итерациялау мүмкін емес. Ұсынылатын балама тәсіл — , онда биттік өріс орнына int enum қолданылады. Бұл тәсіл бір типке жататын мәндер жиынтығын көрсету үшін қолданылады. Интерфейсін іске асыратындықтан және енді биттік операцияларды қажет етпейтіндіктен, бұл тәсіл типтік қауіпсіздікке ие. Сонымен қатар, объектіні құруға мүмкіндік беретін көптеген статикалық фабрикалар бар, мысалы, әдіс әдісі. енгізілгеннен кейін биттік өріс бейнелеу тәсілі ескірген деп есептеледі.
of these elements. A recommended alternative approach is to use an , where an int enum is used instead of a bit field. This approach uses an to represent the set of values that belong to the same type. Since the implements the interface and no longer requires the use of bit wise operations, this approach is more type safe. Furthermore, there are many static factories that allow for object instantiation, such as the method method. After the introduction of the , the bit field representation approach is considered to be obsolete.
HashSet класы
HashSet хэш-кестесін пайдаланады. Нақтырақ айтқанда, ол хэштер мен элементтерді сақтау және дубликаттарды болдырмау үшін хэш-кестені қолданады.
LinkedHashSet класы
java.util.LinkedHashSet класы барлық элементтерді қосылған тәртібімен байланыстыратын екі жақты тізім құру арқылы жұмыс істейді. Бұл жиын бойынша итерация тәртібінің болжамды болуын қамтамасыз етеді.
CopyOnWriteArraySet класы
синхрондалғанның бір мезгілдегі орнын алмастырады. Синхрондау қажеттілігін жою немесе итерация кезінде объектінің көшірмесін жасау қажеттілігін жою арқылы көптеген жағдайларда жақсырақ бір мезгілделікті ұсынады, бұл сияқты синхрондалғанға бір мезгілдегі орнын алмастыруға ұқсас. Алайда, сияқты, синхрондау міндетті болғанда қолданылмауы керек.
SortedSet интерфейсі
Жаваның `util` пакетіндегі `SortedSet` интерфейсі `java.util.Set` интерфейсін кеңейтеді. Қарапайым `Set`-тен айырмашылығы, `SortedSet`-тегі элементтер элементтің өзіндегі `compareTo` әдісімен немесе `SortedSet` конструкторына берілген әдіс арқылы сұрыпталады. `SortedSet`-тің бірінші және соңғы элементтерін тиісінше `first()` және `last()` әдістерін қолдана отырып алуға болады, ал кіші жиынтықтарды ең кішкентай және ең үлкен мәндер арқылы, сондай-ақ `SortedSet`-тің басынан немесе соңынан бастау немесе аяқтау арқылы жасауға болады. `java.util.TreeSet` класы `SortedSet` интерфейсін іске асырады.
NavigateSet интерфейсі
Интерфейс java.util.SortedSet интерфейсін кеңейтеді және бірнеше қосымша әдістерге ие. , , , және әдістері жиынтықтағы параметрге ең жақын элементті табады. Бұдан өзге, жиынтықтағы элементтер бойынша төмендеу итераторы ұсынылады. SortedSet сияқты, java.util.TreeSet NavigableSet интерфейсін іске асырады.
TreeSet класы
Java.util.TreeSet қызыл-қара ағашын қолданады. Қызыл-қара ағашы дубликаттардың болмауын қамтамасыз етеді. Бұдан бөлек, TreeSet-ке мүмкіндік береді.
ConcurrentSkipListSet класы
Бұл синхрондалған әдістің орындалуын бірден алмастырады. Мысалы, ол `method` әдісімен оралған `object` нысанын ауыстырады.
Карта интерфейстері
Карталар Java-дағы интерфейс арқылы анықталады.
Карталық интерфейс енгізулері
Карталар – кілтті элементпен байланыстыратын дерек құрылымдары. Бұл картаны өте икемді етеді. Егер кілт элементтің хэш-коды болса, карта, әдетте, жиынтық болып табылады. Егер кілт үздіксіз өсетін сан болса, ол тізімге айналады. Іске асыру мысалдары: , , және .
AbstractMap класы
скелеттік іске асырудың мысалы болып табылады. кластың тікелей туынды кластарына , , , , және кіреді.
EnumMap (есептеу)
кеңейтіледі және ординалды индекстелген массивпен шамалас жылдамдыққа ие. Бұл оның ішінде массивті пайдалануының арқасы, ал әзірлеушіге оның іске асылу егжей-тегжейлері толығымен жасырын. Сондықтан EnumMap массивтің өнімділік артықшылықтарымен қатар, типтік қауіпсіздікті де қамтамасыз етеді.
HashMap (жазу картасы)
хэш-кестесі қолданылады. Кілттердің хэштері әртүрлі контейнерлердегі элементтерді табу үшін пайдаланылады. Бұл хэш негізінде құрылған жиын.
LinkedHashMap-пен байланысты
элементтер арасында екі жақты тізім құру арқылы кеңейтіледі, бұл оларға картаға енгізілген ретімен қол жеткізуге мүмкіндік береді. Жаңа кілт картаға қосылғанда put әдісі шақыратын, қорғалған removeEldestEntry әдісін қамтиды. Карта ең ескі жазбасын removeEldestEntry true мәнін қайтарғанда жояды. removeEldestEntry әдісін қайта анықтауға болады.
Ағаш картасы
, және сияқты, қызыл-қара ағаш пайдаланады. Кілттер ағаштағы түйіндердің мәні ретінде қолданылады, ал түйіндер Картадағы элементтерге көрсетіледі.
ConcurrentHashMap (Бір мезгілдегі хэш- карта)
ұқсас және хэш негізінде құрылған жиынтық болып табылады. Дегенмен, олардың қолданатын құлыптау стратегияларындағы айырмашылықтар сияқты бірнеше ерекшеліктері бар. Бұл кеңейтілген мүмкіндіктер мен бір мезгілде жұмыс істеуді қамтамасыз ету үшін мүлдем басқа құлыптау стратегиясын қолданады. Барлық әдістерді бір құлыппен синхрондамайды. Оның орнына, құлыптау жолақтары деп аталатын механизмді пайдаланады. Бұл механизм құлыптаудың дәлдігін арттырады. Сонымен қатар, ортақ қол жеткізу деңгейін жоғарылатады.
ConcurrentSkipListMap класы
синхрондалған іске асырылымдарын алмастыру үшін бір мезгілде жұмыс істейді, себебі ол әдіс арқылы оралған -ты ауыстырады.
SortedMap интерфейсі
Интерфейс java.util.Map интерфейсін кеңейтеді. Бұл интерфейс кілттері бойынша сұрыпталған Map-ты анықтайды. Тағы да, compareTo әдісін немесе SortedMap конструкторына берілген әдісті пайдаланып, кілт-элемент жұптары кілттері бойынша сұрыпталады. Map-тағы бірінші және соңғы кілттерді тиісінше және әдістерін қолдана отырып алуға болады. Сонымен қатар, ең төменгі және ең жоғары кілттерден кіші карталарды жасау үшін әдіс қолданылады. SortedMap java.util.TreeMap арқылы іске асырылады.
NavigableMap интерфейсі
Интерфейс java.util.SortedMap-ты әр түрлі жолдармен кеңейтеді. Әдістерді шақыруға болады, олар берілген кілтке ең жақын кілт немесе карта жазбасын екі бағытта табуға мүмкіндік береді. Картаны кері ретте де аударуға болады, сондай-ақ одан кері реттегі итератор жасауға болады. Ол java.util.TreeMap арқылы іске асырылады.
ConcurrentMap интерфейсі
Интерфейс java.util.Map интерфейсін кеңейтеді. Бұл интерфейс Java бағдарламалау тілінің Java Collections Framework 1.5 нұсқасынан бастап енгізілген, қауіпсіз, көп жіпті қолдауға арналған интерфейс.
Java жинақтары аясының кеңейтулері
Java коллекциялары фреймворкі Apache Commons Collections кітапханасымен толықтырылады, ол қап (bag) және екі жақты карта (bidirectional map) сияқты қосымша коллекция түрлерін, сондай-ақ бірілімдер (unions) мен қиылыстар (intersections) жасауға арналған қосымша құралдарды ұсынады. Google өз коллекция кітапханаларын Guava кітапханаларының бөлігі ретінде жариялады.