java map join_HashMap 常见应用:实现 SQL JOIN
在我的上一篇文章中,講到了我自己初步認(rèn)識(shí) HashMap 的一個(gè)經(jīng)驗(yàn)分享:HashMap 淺析 —— LeetCode Two Sum 刷題總結(jié)。作為一個(gè) CRUD 工程師,平時(shí)很少接觸到基礎(chǔ)組件的涉及,那么是不是很難有機(jī)會(huì)用到 HashMap 呢?
今天,就舉一個(gè)常見(jiàn)的查詢(xún)例子,來(lái)看看我們?nèi)绾问褂?HashMap 來(lái)提高代碼的效率。
已知一個(gè) Student 類(lèi):
public class Student {
private Long id;
private String name;
public Student(Long id, String name) {
this.id = id;
this.name = name;
}
// ---Getters And Setters---
}
和一個(gè) Score 類(lèi):
public class Score {
private Long studentId;
private String mathScore;
private String englishScore;
public Score(Long studentId, String mathScore, String englishScore) {
this.studentId = studentId;
this.mathScore = mathScore;
this.englishScore = englishScore;
}
// ---Getters And Setters---
}
我們需要把 Student 和 Score 合并到一起,即類(lèi) Report:
public class Report {
private Long studentId;
private String studentName;
private String mathScore;
private String englishScore;
public Report(Long studentId, String studentName, String mathScore, String englishScore) {
this.studentId = studentId;
this.studentName = studentName;
this.mathScore = mathScore;
this.englishScore = englishScore;
}
}
看類(lèi)的屬性我們就明白了,這里其實(shí)相當(dāng)于在 Student 和 Score 之間做一個(gè) Join,得到 Report。這是我們?cè)诰幊讨谐R?jiàn)的場(chǎng)景(例如查詢(xún)了訂單中心,用戶(hù)中心,支付中心,合并各個(gè)中心返回的結(jié)果形成一個(gè)表單,因?yàn)楦鱾€(gè)中心是獨(dú)立的微服務(wù),無(wú)法使用 SQL JOIN)。
現(xiàn)有兩個(gè) List:List 和 List:
List students = Arrays.asList(
new Student(1L, "Angle"),
new Student(2L, "Baby")
);
List scores = Arrays.asList(
new Score(1L, "90", "87"),
new Score(2L, "92", "78")
);
在學(xué)會(huì)使用 HashMap 之前,我可能會(huì)做一次雙重循環(huán):
List reports = new ArrayList<>();
for (Student student : students) {
for (Score score : scores) {
if (!student.getId().equals(score.getStudentId())) {
continue;
}
reports.add(
new Report(student.getId(), student.getName(), score.getMathScore(), score.getEnglishScore())
);
break;
}
}
時(shí)間復(fù)雜度最差的情況下是O(n * m)。
但是使用 HashMap 來(lái)改善程序,就能得到不錯(cuò)的效果:
Map map = new HashMap<>();
for (Student student : students) {
map.put(student.getId(), student);
}
List reports = new ArrayList<>();
for (Score score : scores) {
Student student = map.get(score.getStudentId());
if(student == null){ // 避免 NPE
continue;
}
reports.add(
new Report(student.getId(), student.getName(), score.getMathScore(), score.getEnglishScore())
);
}
雙重循環(huán),變成了兩次循環(huán),時(shí)間復(fù)雜度是O(n + m)。
顯然要比前面的方法效果要好一些。筆者寫(xiě)了測(cè)試代碼分別測(cè)試兩個(gè)方法的效率,在 10w 數(shù)據(jù)下,執(zhí)行時(shí)間如下:
差距好像挺大。想了解為什么 HashMap 能夠得到如此好的效果,可以看我的這篇文章:HashMap 淺析 —— LeetCode Two Sum 刷題總結(jié)。如果讀者有更好的解法歡迎留言交流,筆者水平有限,在算法上研究不多。
10w 數(shù)據(jù)的測(cè)試源碼見(jiàn)下方,各位讀者可以自行試驗(yàn)下效果:
package com.xiangyu.demo.hashmap;
import com.xiangyu.java.hashmap.Report;
import com.xiangyu.java.hashmap.Score;
import com.xiangyu.java.hashmap.Student;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HashMapTest {
private List students = new ArrayList<>();
private List scores = new ArrayList<>();
@Before
public void before() {
// 每個(gè)list 里放 10w 數(shù)據(jù)
for (long i = 0; i < 100000; i++) {
students.add(new Student(i, "test"));
scores.add(new Score(i, "95", "95"));
}
}
@Test
public void TestHashMap() {
Map map = new HashMap<>();
for (Student student : students) {
map.put(student.getId(), student);
}
List reports = new ArrayList<>();
for (Score score : scores) {
Student student = map.get(score.getStudentId());
if (student == null) {
continue;
}
reports.add(
new Report(student.getId(), student.getName(), score.getMathScore(), score.getEnglishScore())
);
}
System.out.println(reports.size());
}
@Test
public void testFor2() {
List reports = new ArrayList<>();
for (Student student : students) {
for (Score score : scores) {
if (!student.getId().equals(score.getStudentId())) {
continue;
}
reports.add(
new Report(student.getId(), student.getName(), score.getMathScore(), score.getEnglishScore())
);
break;
}
}
System.out.println(reports.size());
}
}
總結(jié)
以上是生活随笔為你收集整理的java map join_HashMap 常见应用:实现 SQL JOIN的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: git 开源 java_开源中国GIT中
- 下一篇: java 拼sql最大长度,java.s