Философия Java3
Шрифт:
stack2.push(s); while( !stack2 emptyO)
System.out print(stack2.pop + " ").
}
fleas has dog My fleas has dog My *///:-
В java.util нет общего интерфейса Stack — вероятно, из-за того, что имя было задействовано в исходной, неудачно спроектированной версии java. util.Stack для Java 1.0. Хотя класс java.util.Stack существует, LinkedList обеспечивает более качественную реализацию стека, и решение net.mindview.util. Stack является предпочтительным.
Множество
В множествах (Set) каждое значение может храниться только в одном экземпляре. Попытки добавить новый экземпляр эквивалентного объекта блокируются. Множества часто используются для проверки
Set имеет такой же интерфейс, что и Collection. В сущности, Set и является Collection, но обладает несколько иным поведением (кстати, идеальный пример использования наследования и полиморфизма: выражение разных концепций поведения). Пример использования HashSet с объектами Integer:
//• hoiding/SetOfInteger.java import java.util.*,
public class SetOfInteger {
public static void main(String[] args) { Random rand = new Random(47); Set<Integer> intset = new HashSet<Integer>: for(int i = 0: i < 10000; i++)
i ntset.add(rand.nextInt(30)): System.out.printin(intset):
}
} /* Output:
[15, 8, 23, 16, 7, 22, 9, 21, 6, 1, 29, 14, 24, 4, 19, 26, 11, 18, 3, 12, 27, 17, 2, 13, 28, 20, 25, 10, 5, 0] *///:-
В множество включаются десять тысяч случайных чисел от 0 до 29; естественно, числа должны многократно повторяться. Но при этом мы видим, что в результатах каждое число присутствует только в одном экземпляре.
Также обратите внимание на непредсказуемый порядок следования чисел в выводе. Это объясняется тем, что HashSet использует хеширование для ускорения выборки. Порядок, поддерживаемый HashSet, отличается от порядка TreeSet или LinkedHashSet, поскольку каждая реализация упорядочивает элементы по-своему. Если вы хотите, чтобы результат был отсортирован, воспользуйтесь TreeSet вместо HashSet:
// hoiding/SortedSetOfInteger java import java util.*.
public class SortedSetOfInteger {
public static void main(String[] args) { Random rand = new Random(47), SortedSet<Integer> intset = new TreeSet<Integer>, for(int i = 0. i < 10000; i++)
i ntset.add(rand.nextInt(30)); System.out println(intset);
}
} /* Output-
[0. 1. 2. 3. 4. 5. 6, 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29] *///.-
Одной из наиболее распространенных операций со множествами является проверка принадлежности методом contains, но существуют и другие операции, которые напомнят вам диаграммы Венна из школьного курса:
// holding/SetOperations java import java.util.*.
import static net.mindview.util.Print.*;
public class SetOperations {
public static void main(String[] args) {
Set<String> setl = new HashSet<String>; Col 1ecti ons.addAl1(setl.
"ABCDEFGHIJK L".splitC ")). setl.addCM");
printCH " + setl containsCH"));
printCN " + setl containsCN"));
Set<String> set2 = new HashSet<String>;
Col 1 ecti ons. addAl l(set2. "H I J К L" splitC "));
print("set2 in setl- " + setl containsAll(set2));
setl.removeCH");
print("setl. " + setl);
print("set2 in setl- " + setl.containsAll(set2)); setl removeAll(set2); printCset2 removed from setl: " + setl). Collections.addAll (setl. "X Y Z".splitC ")). printC'X Y Г added to setl. " + setl);
}
} /* Output H. true N- false
set2 in setl: true
setl: [D.
К. С. B. L. G. I. M. A. F. J. E] set2 in setl- falseset2 removed from setl- [D. С. B. G. M. A. F. E] 'X Y Г added to setl: [Z. D. С. B. G. M. A. F. Y. X. E] *///.-
Имена методов говорят за себя. Информацию о других методах Set можно найти в документации JDK.
Карта
Возможность отображения одних объектов на другие (ассоциация) чрезвычайно полезна при решении широкого класса задач программирования. В качестве примера рассмотрим программу, анализирующую качество распределения класса Java Random. В идеале класс Random должен выдавать абсолютно равномерное распределение чисел, но чтобы убедиться в этом, необходимо сгенерировать большое количество случайных чисел и подсчитать их количество в разных интервалах. Множества упрощают эту задачу: ключом в данном случае является число, сгенерированное при помощи Random, а значением — количество его вхождений:
// holding/Statistics java
// Простой пример использования HashMap
import java util *.
public class Statistics {
public static void main(String[] args) { Random rand = new Random(47). Map<Integer,Integer> m =
new HashMap<Integer.Integer>, for(int i = 0, i < 10000. i++) {
// Получение случайного числа от 0 до 20. int г = rand nextInt(20). Integer freq = m get(r). m.put(r. freq == null ? 1 freq +1).
}
System out println(m);
}
} /* Output
{15=497. 4=481. 19=464. 8=468. 11=531, 16=533, 18=478, 3=508, 7=471, 12=521, 17=509, 2=489, 13=506, 9=549, 6=519, 1=502, 14=477, 10=513, 5=503, 0=481} *///•-
В main механизм автоматической упаковки преобразует случайно сгенери-рованое целое число в ссылку на Integer, которая может использоваться с HashMap (контейнеры не могут использоваться для хранения примитивов). Метод get возвращает null, если элемент отсутствует в контейнере (то есть если число было сгенерировано впервые. В противном случае метод get возвращает значение Integer, связанное с ключом, и последнее увеличивается на 1 (автоматическая упаковка снова упрощает вычисления, но в действительности при этом выполняются преобразования к Integer и обратно).
Следующий пример демонстрирует поиск объектов Pet по строковому описанию String. Он также показывает, как проверить присутствие некоторого ключа или значения в Map методами containsKey и containsValue:
// holding/PetMap java import typeinfo.pets.*, import java util *;
import static net mindview util Print *;
public class PetMap {
public static void main(String[] args) {
Map<String,Pet> petMap = new HashMap<String.Pet>. petMap put ("My Cat", new CatCMolly")). petMap put("My Dog", new Dog("Ginger")). petMap put ("My Hamster", new HamsterCBosco")). print(petMap).
Pet dog = petMap get("My Dog"), print(dog).
print(petMap containsKeyC'My Dog")), pri nt(petMap.contai nsValue(dog)).
}
} /* Output-
{My Cat=Cat Molly. My Hamster=Hamster Bosco. My Dog=Dog Ginger}
Dog Ginger
true
true
*///•-
Map, по аналогии с массивами и Collection, легко расширяются до нескольких измерений; достаточно создать Map со значениями типа Map (причем значениями этих Map могут быть другие контейнеры, и даже другие Map). Контейнеры легко комбинируются друг с другом, что позволяет быстро создавать сложные структуры данных. Например, если нам потребуется сохранить информацию о владельцах сразу нескольких домашних животных, для этого будет достаточно создать контейнер Map<Person,List<Pet»: