Въведение в PCollections

1. Общ преглед

В тази статия ще разгледаме PCollections, библиотека на Java, предоставяща постоянни, неизменяеми колекции.

Постоянните структури от данни (колекции) не могат да бъдат модифицирани директно по време на операцията по актуализиране, а по-скоро се връща нов обект с резултата от операцията по актуализиране. Те са не само неизменни, но и постоянни - което означава, че след извършване на модификацията предишните версии на колекцията остават непроменени.

PCollections е аналогичен и съвместим с рамката на Java Collections.

2. Зависимости

Нека добавим следната зависимост към нашия pom.xml, за да използваме PCollections в нашия проект:

 org.pcollections pcollections 2.1.2 

Ако нашият проект е базиран на Gradle, можем да добавим същия артефакт към нашия файл build.gradle :

compile 'org.pcollections:pcollections:2.1.2'

Най-новата версия може да бъде намерена на Maven Central.

3. Структура на картата ( HashPMap )

HashPMap е постоянна структура от данни на картата. Това е аналогът за java.util.HashMap, използван за съхраняване на ненулеви данни с ключ-стойност.

Можем да създадем екземпляр на HashPMap, като използваме удобни статични методи в HashTreePMap. Тези статични методи връщат екземпляр на HashPMap, който е подкрепен от IntTreePMap.

Статичният метод празен () на класа HashTreePMap създава празен HashPMap , който няма елементи - точно като използването на конструктора по подразбиране на java.util.HashMap :

HashPMap pmap = HashTreePMap.empty();

Има два други статични метода, които можем да използваме за създаване на HashPMap . Методът singleton () създава HashPMap само с един запис:

HashPMap pmap1 = HashTreePMap.singleton("key1", "value1"); assertEquals(pmap1.size(), 1);

Методът from () създава HashPMap от съществуващ екземпляр java.util.HashMap (и други реализации на java.util.Map ):

Map map = new HashMap(); map.put("mkey1", "mval1"); map.put("mkey2", "mval2"); HashPMap pmap2 = HashTreePMap.from(map); assertEquals(pmap2.size(), 2);

Въпреки че HashPMap наследява някои от методите от java.util.AbstractMap и java.util.Map , той има уникални за него методи.

Методът minus () премахва един запис от картата, докато методът minusAll () премахва множество записи. Има и методите plus () и plusAll () , които добавят съответно единични и множество записи:

HashPMap pmap = HashTreePMap.empty(); HashPMap pmap0 = pmap.plus("key1", "value1"); Map map = new HashMap(); map.put("key2", "val2"); map.put("key3", "val3"); HashPMap pmap1 = pmap0.plusAll(map); HashPMap pmap2 = pmap1.minus("key1"); HashPMap pmap3 = pmap2.minusAll(map.keySet()); assertEquals(pmap0.size(), 1); assertEquals(pmap1.size(), 3); assertFalse(pmap2.containsKey("key1")); assertEquals(pmap3.size(), 0);

Важно е да се отбележи, че извикването на put () на pmap ще хвърли UnsupportedOperationException. Тъй като обектите на PCollections са постоянни и неизменни, всяка модифицираща операция връща нов екземпляр на обект ( HashPMap ).

Нека да продължим да разглеждаме други структури от данни.

4. Структура на списъците ( TreePVector и ConsPStack )

TreePVector е постоянен аналог на java.util.ArrayList, докато ConsPStack е аналогът на java.util.LinkedList . TreePVector и ConsPStack имат удобни статични методи за създаване на нови екземпляри - точно като HashPMap .

Методът empty () създава празен TreePVector , докато методът singleton () създава TreePVector само с един елемент. Съществува и методът from () , който може да се използва за създаване на екземпляр на TreePVector от всеки java.util.Collection .

ConsPStack има статични методи със същото име, които постигат същата цел.

TreePVector има методи за манипулиране с него. Той има методите minus () и minusAll () за премахване на елемент (и); на плюс () , и plusAll () за добавяне на елемент (и).

The with () се използва за замяна на елемент с определен индекс, а subList () получава набор от елементи от колекцията.

Тези методи са достъпни и в ConsPStack .

Нека разгледаме следния кодов фрагмент, който илюстрира методите, споменати по-горе:

TreePVector pVector = TreePVector.empty(); TreePVector pV1 = pVector.plus("e1"); TreePVector pV2 = pV1.plusAll(Arrays.asList("e2", "e3", "e4")); assertEquals(1, pV1.size()); assertEquals(4, pV2.size()); TreePVector pV3 = pV2.minus("e1"); TreePVector pV4 = pV3.minusAll(Arrays.asList("e2", "e3", "e4")); assertEquals(pV3.size(), 3); assertEquals(pV4.size(), 0); TreePVector pSub = pV2.subList(0, 2); assertTrue(pSub.contains("e1") && pSub.contains("e2")); TreePVector pVW = (TreePVector) pV2.with(0, "e10"); assertEquals(pVW.get(0), "e10");

В кодовия фрагмент по-горе pSub е друг обект TreePVector и е независим от pV2 . Както може да се забележи, pV2 не беше променен от операцията subList () ; по-скоро беше създаден нов обект TreePVector и изпълнен с елементи на pV2 от индекс 0 до 2.

Това се разбира под неизменност и се случва с всички модифициращи методи на PCollections.

5. Задайте структура ( MapPSet )

MapPSet е постоянен, защитен с карта, аналог на java.util.HashSet . Той може да бъде удобно създаден чрез статични методи на HashTreePSet - empty () , from () и singleton () . Те функционират по същия начин, както е обяснено в предишните примери.

MapPSet има методи plus () , plusAll () , minus () и minusAll () за манипулиране на зададени данни. Освен това наследява методи от java.util.Set , java.util.AbstractCollection и java.util.AbstractSet :

MapPSet pSet = HashTreePSet.empty() .plusAll(Arrays.asList("e1","e2","e3","e4")); assertEquals(pSet.size(), 4); MapPSet pSet1 = pSet.minus("e4"); assertFalse(pSet1.contains("e4"));

И накрая, има и OrderedPSet - който поддържа реда на вмъкване на елементи точно като java.util.LinkedHashSet .

6. Заключение

В заключение в този бърз урок разгледахме PCollections - постоянните структури от данни, които са аналогични на основните колекции, които имаме в Java. Разбира се, PCollections Javadoc предоставя по-голяма представа за тънкостите на библиотеката.

И както винаги, пълният код може да бъде намерен в Github.