О наборе «Коллекция гуавы»
Guava предоставляет множество пакетов сбора, которые очень удобны для бизнес-операций.В этой статье сравнивается использование пакета сбора Guava и неприменимого пакета сбора Guava, чтобы увидеть, какое удобство пакет сбора Guava обеспечивает нашим операциям сбора.
Приложения в обработке коллекции
Список групп
Введение в бизнес: Существует список заказов, который содержит несколько заказов от нескольких пользователей.Нам нужно сгруппировать список заказов в соответствии с пользователями.
Класс приложения
ArrayListMultimap, конечно, Гуава тоже предоставляет LinkedListMultimap, апи аналогично, но коллекция хранимых значений заменена на LinkedList
добиться контраста
/**
* 订单实体
*/
public class Order {
private String userId;
private String orderId;
private Double price;
private Date createTime;
private Date updateTime;
}
public class Test {
/**
* 自己实现分组
*/
public void group(List<Order> orderList) {
Map<String, List<Order>> userOrdersMap = new HashMap<>();
for(Order order: orderList) {
String userId = order.getUserId();
if(userOrdersMap.containsKey(userId)) {
userOrdersMap.get(userId).add(order);
} else {
List<Order> orders = new ArrayList<>();
orders.add(order);
userOrdersMap.put(user, orders);
}
}
}
/**
* 使用Guava进行分组分组
*/
public void guavaGroup(List<Order> orderList) {
ArrayListMultimap<String, Order> arrayListMultimap = ArrayListMultimap.create();
orderList.forech(e -> arrayListMultimap.put(e.getUserId(), e));
// ArrayListMultimap 常用API asMap() get(key)返回值为List<T>
}
}
В заключение
Глядя на исходный код Guava, вы обнаружите, что метод put ArrayListMultimap похож на нашу собственную логику кода для реализации группировки. ArrayListMultimap эквивалентен инкапсуляции наших общих бизнес-операций со списками. При работе с проектами со многими бизнес-списками введение Guava может уменьшить сложность нашего кода. , более ориентированный на реализацию основного бизнеса.
Храните баллы нескольких студентов и нескольких предметов, подсчитывайте общий балл студентов и оценку комментариев по предмету класса.
В базе данных есть таблица, в которой хранятся результаты тестов по всем предметам всех учащихся в классе, считывается вся информация о баллах и вычисляется общий балл каждого учащегося и средний балл по предметам в классе.
образец данных
Имя | предмет | Доля | семестр | сорт |
---|---|---|---|---|
Чжан Сан | язык | 95 | на 2021 год | Второй класс за три года |
Чжан Сан | математика | 80 | на 2021 год | Второй класс за три года |
Ван Ву | язык | 90 | на 2021 год | Второй класс за три года |
Ван Ву | математика | 75 | на 2021 год | Второй класс за три года |
Структура таблицы
CREATE TABLE `test_score` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`student_name` varchar(255) NOT NULL COMMENT '学生姓名',
`subject` varchar(255) NOT NULL COMMENT '科目',
`semester` varchar(255) NOT NULL COMMENT '学期',
`score` double NOT NULL COMMENT '分数',
`class_grade` varchar(255) NOT NULL COMMENT '班级',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Деловая сцена
Статистика результатов тестов класса, статистика общего балла каждого учащегося, средний балл по предмету в классе, средний балл общего балла в классе и обобщение в статистическую информацию.
бизнес-анализ
Если такой статистический бизнес обрабатывается sql, каждый бизнес должен быть sql-запросом и агрегирован отдельно, как показано ниже:
- Общий балл для каждого ученика
select student_name, sum(score) gross_score from test_score where semester = '2021上' and class_grade = '三年二班' group by student_name;
- Средний предмет класса
select subject,avg(score) as avg from test_score where semester = '2021上' and class_grade = '三年二班' group by subject;
- средний класс
SELECT avg(t.sum) avg FROM (SELECT sum(score) AS sum FROM test_score WHERE semester = '2021上' AND class_grade = '三年二班' GROUP BY student_name) AS t
Такой SQL относительно прост, но для бизнеса требуется три взаимодействия с базой данных, а также разработаны несколько операций и групп функций SQL.Конечный результат все еще необходимо агрегировать, будь то на уровне базы данных или на уровне кода, это относительно Это сложен и не способствует обслуживанию.Далее я буду использовать HashBasedTable от Guava, чтобы решить эту проблему, уменьшить операции SQL и сложность SQL, а сложность кода низкая.
Код
- Выполните общий запрос, чтобы получить оценки всех учащихся во втором семестре третьего курса и во втором классе 2021 года, а возвращенные результаты сопоставляются со списком.
SELECT student_name, subject,semester,score,class_grade FROM test_score WHERE semester = '2021上' AND class_grade = '三年二班'
/**
* 学生科目成绩实体
*/
public class TestScore {
private String studentName;
private String subject;
private String semester;
private Double score;
private classGrade;
// 省略get set toString ...
}
/**
* 统计业务实现示例
*/
public class TestScoreService {
/**
* 使用假数据进行测试 真是场景 testScoreList通过执行上面sql获得
*/
public static void main(String[] args) {
TestScore t1 = new TestScore("张三", "语文", "三年二班", 80D, "2021上");
TestScore t2 = new TestScore("张三", "数学", "三年二班", 80D, "2021上");
TestScore t3 = new TestScore("李四", "语文", "三年二班", 100D, "2021上");
TestScore t4 = new TestScore("李四", "数学", "三年二班", 90D, "2021上");
ArrayList<TestScore> testScoreList = Lists.newArrayList(t1, t2, t3, t4);
// 2.初始化HashBasedTable HashBasedTable<R, C, V> R相当行 就是学生姓名 C 相当于列 就是科目
HashBasedTable<String, String, Double> table = HashBasedTable.create();
for (TestScore testScore : testScoreList) {
table.put(testScore.getStudentName(), testScore.getSubject(), testScore.getScore());
}
//3.计算每个学生的总分
Map<String, Map<String, Double>> studentSubjectScoreMap = table.rowMap();
Map<String, Double> studentGrossScoreMap = Maps.newHashMap();
for (Map.Entry<String, Map<String, Double>> entry : studentSubjectScoreMap.entrySet()) {
String studentName = entry.getKey();
// 总分
double grossScore = entry.getValue().values().stream().mapToDouble(e -> e).sum();
studentGrossScoreMap.put(studentName, grossScore);
}
// 4.计算班级总分平均分
double grossScoreAvg = studentGrossScoreMap.values().stream().mapToDouble(e -> e).average().orElse(-1);
// 5.计算科目平均分
Map<String, Map<String, Double>> subjectStudentScoreMap = table.columnMap();
Map<Object, Object> subjectScoreAvgMap = Maps.newHashMap();
for (Map.Entry<String, Map<String, Double>> entry : subjectStudentScoreMap.entrySet()) {
String subject = entry.getKey();
// 科目平均分
double subjectScoreAvg = entry.getValue().values().stream().mapToDouble(e -> e).average().orElse(-1);
subjectScoreAvgMap.put(subject, subjectScoreAvg);
}
// 学生总分
System.out.println(studentGrossScoreMap);
// 班级科目平均分
System.out.println(subjectScoreAvgMap);
// 班级总分平均分
System.out.println(grossScoreAvg);
}
}
Результаты
{李四=190.0, 张三=160.0}
{数学=85.0, 语文=90.0}
175.0
Резюме использования HashBasedTable
В соответствии с приведенным выше бизнес-сценарием использование HashBasedTable заключается в инкапсуляции нашей структуры данных в таблицу Excel с собственными строками и столбцами.Мы помещаем оценки по каждому предмету учащихся в одну строку, а оценки по одному и тому же предмету в тот же столбец, используйте предоставленный API rowMap(), columnMap(), чтобы помочь нам быстро получить данные строки или столбца, а затем выполнить расчетную обработку
BiMap
BiMap поддерживает двустороннее сопоставление и может находить значения по ключу.
Пример
public class Demo {
public static void main(String[] args) {
BiMap<String, Integer> biMap = HashBiMap.create();
biMap.put("张三", 28);
String name = biMap.inverse().get(28);
// put已经存在的值会抛出异常
// biMap.put("李四", 28); // 抛出IllegalArgumentExceptionvalue: already present: 28
// 使用forcePut()可以避免异常
biMap.forcePut("李四", 28);
}
}
В заключение
bimap обеспечивает двустороннее обслуживание отношений, но бизнес должен гарантировать, что значение уникально.Если оно не уникально, вам нужно использовать forcePut
Суммировать
Guava предоставляет множество коллекций, которые помогают нам решать бизнес-задачи.Мы знакомы с характеристиками различных коллекций, понимаем их структуры данных и можем быстро выбрать коллекции, подходящие для нашего собственного бизнеса, для обработки данных после ознакомления с требованиями.