Я написал много статей, связанных с классами коллекций Java, и узнал, как использовать множество классов коллекций. Считаете ли вы, что все еще существуют некоторые общие требования, которым классы коллекций не могут соответствовать? Вам нужно использовать классы в коллекциях Java для реализуйте их самостоятельно, но для нас были построены такие широко используемые колеса Google и apache.
Есть два хорошо известных инструментария, связанных с Java:Google Guava
иApache Commons
, Сегодня давайте взглянем на некоторые другие классы коллекций, реализованные в Guava, которые в основном улучшены по сравнению с классами коллекций JDK.
Неизменяемые коллекции -> настоящие неизменяемые коллекции
вышеJava Collections, упомянулCollections
Класс предоставляет несколько методов, которые могут возвращать неизменное представление коллекции, давайте сейчас попробуем.
Мы создаем новый список из 5 элементов, затем создаем для него неизменяемый вид.
List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
List<Integer> umList = Collections.unmodifiableList(list);
После вышеперечисленных действий мы получилиumList
, который неизменен, ноlist
не ушел, он все еще изменчив, и мы можем сделать это, давlist
добавить значение для измененияumList
набор элементов.
Так какCollections.unmodifiableList
, держитlist
, все изменения в списке также будут отражены вumList
начальство.
И в приведенном выше коде есть дополнительная промежуточная переменнаяlist
.потому что он нам не нужен, мы создаем его только для того, чтобы получить неизменяемую коллекцию.Более утомительно.
использоватьGuava
Как это сделать?
ImmutableCollection li = ImmutableList.of(1, 2, 3, 4, 5);
Ощущается ли это намного яснее, в то же время, этоli
действительно неизменен.
ImmutableList также предоставляет различные методы создания, такие как:
- Непосредственно создается с аргументами любого количества элементов.
- использовать
copyOf
Создать из существующего списка - Предоставляет шаблон Builder для цепочки вызовов.
Код выше начинается сImmutableList
пример, ноGuava
также обеспечиваетImmutableSet
,ImmutableMap
,ImmutableCollection
и другие классы, которые можно вызывать отдельно в соответствии с требуемой структурой данных.
Другое решение для MultiMap -> Map
У нас часто возникает необходимость хранить список/набор в структуре карты.
Например, чтобы подсчитать дату регистрации пользователя для рисования календаря, нам нужны следующие данные:name->[2019-04-01,2019-04-28]
структура данных такая.
Тогда давайте присоединимся к пользователю, чтобы проверить запись о входе в систему 1 мая? Напишите небольшой код,
// 模拟已有的数据结构
static Map<String, List<String>> userSign = new HashMap<>();
// 新放进去一条数据
public static void putIt(String name, String date) {
// 正式的逻辑部分
List<String> dates = userSign.getOrDefault(name, new ArrayList<>());
if (!dates.contains(date)) {
dates.add(date);
}
userSign.put(name, dates);
}
Видно, что это более неприятно, и если нет картыgetOrDefault()
метода, есть еще несколько строк кода, потому что его приходится делить на существующий и несуществующий..
Guava предоставляет структуру данных для предотвращения ситуации, когда ключ соответствует нескольким значениям, то естьMultiMap
.
Хотя его имя носитmap
, но глядя на исходный код, можно обнаружить, что его class life не наследует интерфейс Map.
нужно использоватьMultiMap
Для реализации вышеуказанного метода, как это:
ArrayListMultimap<String, String> userSign = ArrayListMultimap.create();
userSign.put("huyan", "2019-05-01");
userSign.put("huyan", "2019-05-02");
List<String> huyanSign = userSign.get("huyan");
Да, просто заявляйте его напрямую, когда вы хотите потреблять, используйте метод получения, чтобы получитьArratlist
, операция обхода может быть выполнена.
Скачав исходный код Guava, вы можете обнаружить, что на самом деле он реализован с помощью Map
Вы можете видеть, что он определен:Map<K,Collection<V>
.определяется какCollection
Это реализация других централизованных структур данных.
Например:
-
HashMultimap
Значение помещается в набор -
LinkedListMultimap
Значение помещается в LinkedList.
и Т. Д.
Multiset -> счетчик с именем set
Честно говоря, это очень полезно, но почему это называется набором... У всех впечатление от набора состоит в том, что повторяющиеся элементы нельзя размещать, аMultiset
Функция состоит в подсчете повторяющихся элементов.
Он используется следующим образом:
Multiset<String> s = HashMultiset.create();
s.add("pf");
s.add("pf");
s.add("pf");
s.add("hh");
// i =3
int i = s.count("pf");
Это так же, как счетчик, который я написал несколько дней назад,встречный портал.
Внутренняя реализация использует HashMap для сохраненияkey->count
отношение отображения .
BiMap -> значение не может повторяться двунаправленная карта
Этот класс действительно реализует интерфейс карты JDK.Чтобы использовать его, вы должны убедиться, что ни ключ, ни значение не имеют повторяющихся значений.Потому что он поддерживает получение ключа в соответствии со значением, то есть ключ и значение HashMap обмениваются .
BiMap<String, String> m = HashBiMap.create();
m.put("pf", "111");
String value = m.get("pf");
String key = m.inverse().get("111");
Этот класс подходит для использования, когда и ключ, и значение уникальны, и часто бывает так, что ключ получается в соответствии со значением.
Таблица -> Карта > решение
При обнаружении нескольких индексов и одного результатаMap<String,Map<String,Object>>
Такая реализация, конечно, возможна, но ее слишком сложно понять и запрограммировать.
Guava предоставляет метод, называемыйTable
Структура данных может быть реализована элегантно.
Используйте следующим образом:
Table<Integer, Integer, String> tt = HashBasedTable.create();
tt.put(1, 2, "huyan");
String name = tt.get(1, 2);
Map<Integer, String> row = tt.row(1);
Map<Integer, String> colum = tt.column(1);
Set<Table.Cell<Integer, Integer, String>> ha = tt.cellSet();
Инициализированные и несколько структур выше не отличаются, она инициализирована статическим фабричным методом, GET и выдвигает методы хранения данных и уникальный индекс на основе двух индексов.
Кроме того, вы также можете получить ряд или столбец конфигурации карты, может получить набор всех ячеек. В значительной степени облегчает процесс, аналогичный таблице данных.
Конечно, если вы посмотрите на исходный код, вы обнаружите, что нижний слой таблицы также реализован путем вложения двух карт, но язык Java полностью посвящен инкапсуляции.Хотя мы можем реализовать это сами, нам нужно сделать следующее: изучить его.Метод реализации ,понять,понять и уметь применять аналогичные идеи в других сценариях,вместо того, чтобы каждый раз писать по две карты.Ведь готовые колеса надо использовать больше для углубления своего понимания в применимых сценариях .
ComparisonChain -> Мощный и красивый метод сравнения нескольких полей
В случае сортировки и сравнения нескольких полей наш код обычно уродлив, например следующий класс:
private static class Student {
int id;
String name;
int age;
}
У нас нет возможности сравнить или отсортировать его сейчас, потому что для него нет определенной стратегии сравнения, предполагая, что наша стратегия такова:
Первый идентификатор сравнения, идентификатор равен имени сравнения, имя равно значению возраста сравненияЭто очень распространенная многосглавная стратегия сравнения. Итак, мы даемStudent
класс плюсComparable
реализация.
// 为了简洁起见,没有写外部类代码,只贴了重写的comparTo方法.
@Override
public int compareTo(Object o) {
Student s = (Student) o;
int idResult = s.id - this.id;
int nameResult = s.name.compareTo(this.name);
int ageResult = s.age - this.age;
return idResult != 0 ? idResult : nameResult != 0 ? nameResult : ageResult;
}
Последняя строка?:?:
Не режут ли глаза, конечно можно выбрать тройку если-иначе, не думаю, что сильно лучше.
Но вы можете использоватьComparisonChain
, это имя выглядит как цепочка сравнения, что очень подходит для нашей сцены. Перепишем так:
@Override
public int compareTo(Object o) {
Student s = (Student) o;
return ComparisonChain.start().compare(s.id, this.id).compare(s.name, this.name).compare(s.age, this.age).
result();
}
Читаемость этого кода была значительно улучшена, семантика очень ясна, и вы можете четко понимать процесс запуска, сравнения, а затем сравнения и возврата результата.
Заказ -> комбинация нескольких компараторов
Приведенная выше ComparisonChain решает ситуацию сортировки нескольких полей при реализации Comparable, поэтому в JDK есть много методов, которым необходимо предоставлять внешние компараторы.Хотим ли мы сейчас сортировать по нескольким компараторам?
Порядок позволяет использовать несколько компараторов, что само по себе реализуетComparator
интерфейс, который может интегрировать несколько компараторов.
Ordering<Student> studentOrdering = Ordering.compound(Arrays.asList((o1, o2) -> {
return ComparisonChain.start().result();
}, (o1, o2) -> 0, (o1, o2) -> 0));
Collections.sort(students, studentOrdering);
В приведенном выше коде порядок используется для интеграции нескольких компараторов, а затем передается вCollections
изsort
Метод, использующий его для сортировки списка.
ChangeLog
2019-05-01 ЗавершениеВсе вышеизложенное является личными мыслями, если есть какие-либо ошибки, пожалуйста, исправьте их в комментариях.
Добро пожаловать на перепечатку, пожалуйста, подпишите и сохраните исходную ссылку.
Контактный адрес электронной почты: huyanshi2580@gmail.com
Дополнительные заметки об обучении см. в личном блоге ------>Хуян тен