86

86


Семейства Arrays и Collections в java.util содержат вспомогательные методы для включения групп элементов в коллекции. Метод Arrays.asList() получает либо массив, либо список элементов, разделенных запятыми, и преобразует его в объект List. Метод Collections.addAUQ получает объект Collection и либо массив, либо список, разделенный запятыми, и добавляет элементы в Collection. Пример:

//• hoiding/AddingGroups java

// Добавление групп элементов в объекты Collection

import java.util *;

public class AddingGroups {

public static void main(String[] args) { Collection<Integer> collection =

new ArrayList<Integer>(Arrays.asList(l, 2, 3, 4, 5)); Integer[] morelnts = { 6. 7. 8. 9. 10 }; collection.addAll(Arrays.asList(morelnts)); // Работает намного быстрее, но таким способом // невозможно сконструировать Collection: Collections.addAll(collection, 11, 12, 13, 14, 15); Col lections.addAll(collection, morelnts); // Создает список на основе массива: List<Integer> list = Arrays.asList(16. 17, 18, 19, 20); list set(l, 99); // Можно - изменение элемента // list.add(21); // Ошибка времени выполнения - нижележащий // массив не должен изменяться в размерах

}

} ///:-

Конструктор Collection может получать другой объект Collection, используе­мый для его инициализации, поэтому для передачи исходных данных можно воспользоваться методом Arrays.asList(). Однако метод Collections.addAll() рабо­тает намного быстрее, и вы с таким же успехом можете сконструировать Collection без элементов, а затем вызвать Collections.addAll — этот способ счита­ется предпочтительным.

Методу Collection.addAll() в аргументе может передаваться только другой объект Collection, поэтому он уступает в гибкости методам Arrays.asList() и Collections.addAll(), использующим переменные списки аргументов.

Также можно использовать вывод Arrays.asList() напрямую, в виде List, но в этом случае нижележащим представлением будет массив, не допускающий изменения размеров. Вызов add() или delete() для такого списка приведет к по­пытке изменения размера массива, а это приведет к ошибке во время выполне­ния.

Недостаток Arrays.asList() заключается в том, что он пытается «вычислить» итоговый тип List, не обращая внимания на то, что ему присваивается. Иногда это создает проблемы:

//: hoiding/AsListInference.java // Arrays.asListO makes its best guess about type, import java.util.*;

class Snow {}

class Powder extends Snow {} class Light extends Powder {} class Heavy extends Powder {} class Crusty extends Snow {} class Slush extends Snow {}

public class AsListInference {

public static void main(String[] args) { List<Snow> snowl = Arrays.asList(

new CrustyO. new SlushO. new PowderO);

// He компилируется- // List<Snow> snow2 = Arrays.asList( // new LightO. new HeavyO); // Сообщение компилятора: //found java.util.List<Powder> // required, java util List<Snow>

II Collections.addAllО работает нормально:

List<Snow> snow3 = new ArrayList<Snow>():

Col 1 ecti ons. addAl 1 (snow3, new LightO. new HeavyO);

II Передача информации посредством уточнения // типа аргумента

List<Snow> snow4 = Arrays <Snow>asList( new LightO, new HeavyO),

}

} ///:-

При попытке создания snow2, Arrays.asList() создает List<Powder> вместо List <Snow>, тогда как Collections.addAll() работает нормально, потому что целевой тип определяется первым аргументом. Как видно из создания snow4, в вызов Arrays.asList() можно вставить «подсказку», которая сообщает компилятору фак­тический тип объекта List, производимого Arrays.asList().

С контейнерами Map дело обстоит сложнее, и стандартная библиотека Java не предоставляет средств их автоматической инициализации, кроме как по со­держимому другого объекта Map.

Вывод содержимого контейнеров

Для получения печатного представления массива необходимо использовать ме­тод Arrays.toString, но контейнеры отлично выводятся и без посторонней по­мощи. Следующий пример демонстрирует использование основных типов кон­тейнеров:

II: ell:Printi ngContai ners.java II Вывод контейнеров по умолчанию import java.util.*;

import static net.mindview.util.Print.*;

public class PrintingContainers {

static Collection fill(Collection<String> collection) { collection. addC'rat"): collection.addC'cat"); collection.adde'dog"): col lection.add("dog"); return collection;

}

static Map fill(Map<String,String> map) {

map. put ("rat", "Fuzzy");продолжение &

map.put("cat". "Rags"), тар.put("dog". "Bosco"); map.put("dog", "Spot"); return map;

}

public static void main(String[] args) {

pri nt(fi11(new ArrayLi st<Stri ng>())); print(fill(new LinkedList<String>())); pri nt(fi11(new HashSet<Stri ng>())); pri nt(fi11(new TreeSet<Stri ng>())); pri nt(fi11(new Li nkedHashSet<Stri ng>())); pri nt(fi11(new HashMap<Stri ng.Stri ng>())); print(fill(new TreeMap<String,String>())); print(fi11(new LinkedHashMap<String,String>()));

}

} /* Output: [rat, cat, dog, dog] [rat, cat. dog, dog] [dog, cat, rat] [cat, dog, rat] [rat. cat. dog]

{dog=Spot. cat=Rags, rat=Fuzzy} {cat=Rags, dog=Spot, rat=Fuzzy} {rat=Fuzzy, cat=Rags, dog=Spot} *///:-

Как уже было упомянуто, в библиотеке контейнеров Java существует две ос­новные категории, различающиеся прежде всего тем, сколько в одной ячейке контейнера «помещается» элементов. Коллекции (Collection) содержат только один элемент в каждой ячейке. К этой категории относятся список (List), где в определенной последовательности хранится группа элементов, множество (Set), в которое можно добавлять только по одному элементу определенного типа, и очередь (Queue). В контейнерах Map (карта) хранятся два объекта: ключ и связанное с ним значение.

Из выходных данных программы видно, что вывод по умолчанию (обеспечи­ваемый методом toStringO каждого контейнера) дает вполне приличные резуль­таты. Содержимое Collection выводится в квадратных скобках, с разделением элементов запятыми. Содержимое Map заключается в фигурные скобки, ключи и значения разделяются знаком равенства (ключи слева, значения справа).

Контейнеры ArrayList и LinkedList принадлежат к семейству List, и из выход­ных данных видно, что элементы в них хранятся в порядке вставки. Они разли­чаются не только скоростью выполнения тех или иных операций, но и тем, что LinkedList содержит больше операций, чем ArrayList.

HashSet, TreeSet и LinkedHashSet относятся к семейству Set. Из выходных дан­ных видно, что в множествах Set каждый элемент хранится только в одном эк­земпляре, а разные реализации Set используют разный порядок хранения эле­ментов. В HashSet порядок элементов определяется по довольно сложному алгоритму — пока достаточно знать, что этот алгоритм обеспечивает минималь­ное время выборки элементов, но порядок следования элементов на первый взгляд выглядит хаотично. Если порядок хранения для вас важен, используйте контейнер TreeSet, в котором объекты хранятся отсортированными по возраста­нию в порядке сравнения, или LinkedHashSet с хранением элементов в порядке добавления.

Report Page