問題背景
這兩天遇到促銷商品在數據庫重複的問題,實在是有一點不好排查。現在也撈不到當時的日誌,也不知道用戶的操作。讓人很是頭大。所以,只能在插入數據庫前對數據做一次去重,保證進入數據庫是不重複的。
如何去重
我能想到的最快捷的方法就是直接把List拋給HashMap,這個時候我們就可以得到一個不重複的Set集合。然後在還原成List。
代碼如下:
HashSet<Object> set=new HashSet<>();
那麼,我們需要來考慮一下HashSet是如何保證不重複的。實際上看到這個名字,我們就知道其一定是基於Hash算法實現的。那麼他在存儲的時候實際上藉助的還是一個HashMap。在存入對象的時候,會調用對象的hashCode()方法,兩個對象的hashcode值是相等的,則判定兩對象相等,於是乎只存在一個。當hashcode不相等的時候,還會去調用equals()方法。最終的判斷兩個對象是否相等。我們可以看得出來,如果想要我們的對象在HashSet中好好的存儲。那我們必須自定義POJO的hashCode方法和equals方法。
自定義方法
在自定義方法的時候我按快捷鍵ctrl+o,按出來的可以重寫的方法我竟然莫有找到。我勒個去!後來我在想是不是POJO頭頂的註解的干擾。實際上我是用了lombok的@Data註解。我一直以爲這個註解只是給POJO添加get以及set方法而已。誰知道,他竟然自己重寫了那兩個方法,所以導致我找不到。
於是我點進@Data的源代碼。如下:
/**
* Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
* all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
* <p>
* Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
* <p>
* Complete documentation is found at <a href="https://projectlombok.org/features/Data.html">the project lombok features page for @Data</a>.
*
* @see Getter
* @see Setter
* @see RequiredArgsConstructor
* @see ToString
* @see EqualsAndHashCode
* @see lombok.Value
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
/**
* If you specify a static constructor name, then the generated constructor will be private, and
* instead a static factory method is created that other classes can use to create instances.
* We suggest the name: "of", like so:
*
* <pre>
* public @Data(staticConstructor = "of") class Point { final int x, y; }
* </pre>
*
* Default: No static constructor, instead the normal constructor is public.
*/
String staticConstructor() default "";
}
它告訴我們完整的文檔在如下位置,文檔。點進去看了一下。寫的是十分詳細。那我也就不必要去寫如何重寫hashCode以及equals方法了。但是大家要記住,如果你要用基於hash算法首先的集合,請一定要重寫他們!
總結
總的來說,還是非常的有收穫的。從一次去重得到的經驗。看來我小看lombok了。下一篇想總結下lombok的常用註解。