在 Java 開發(fā)中,處理數(shù)據(jù)時經(jīng)常會遇到需要刪除重復(fù)數(shù)字的場景,比如從用戶輸入的數(shù)組中提取唯一數(shù)值、統(tǒng)計數(shù)據(jù)集中不重復(fù)的元素等。不同場景下,適合的實現(xiàn)方法有所差異,小編將介紹四種常用的 Java 剔除重復(fù)數(shù)值的方法,包括基于集合、數(shù)組遍歷、排序去重以及 Stream 流的實現(xiàn)方式,幫助開發(fā)者根據(jù)實際需求選擇合適的方案。
方法一:利用 Set 集合自動去重(最簡單高效)
Set 集合是 Java 中的一種無序集合,其核心特性是 “不允許存儲重復(fù)元素”,因此可以直接利用這一特性實現(xiàn)重復(fù)數(shù)字的刪除。該方法無需手動判斷元素是否重復(fù),代碼簡潔,適合大多數(shù)基礎(chǔ)去重場景。
實現(xiàn)步驟分為三步:首先將存儲數(shù)字的數(shù)組或列表轉(zhuǎn)換為 Set 集合,Set 會自動過濾掉重復(fù)元素;然后根據(jù)需求將 Set 集合轉(zhuǎn)回數(shù)組或列表;最后獲取去重后的結(jié)果。以 int 數(shù)組為例,具體代碼如下:
java取消自動換行復(fù)制
若需要保持原始數(shù)組的元素順序,可將HashSet替換為LinkedHashSet,LinkedHashSet會保留元素的插入順序,其他代碼邏輯不變。該方法的時間復(fù)雜度約為 O (n)(n 為元素數(shù)量),效率較高,但 Set 集合無法直接存儲基本數(shù)據(jù)類型,需使用包裝類(如 Integer),不過 Java 的自動裝箱 / 拆箱機制會簡化這一過程。
方法二:數(shù)組遍歷手動去重(適合基礎(chǔ)場景)
若不希望依賴集合類,可通過數(shù)組遍歷的方式手動判斷并剔除重復(fù)元素。該方法需要創(chuàng)建新數(shù)組存儲唯一元素,通過雙重循環(huán)對比元素是否重復(fù),適合對集合類不熟悉或需自定義去重邏輯的場景。
實現(xiàn)思路:先創(chuàng)建一個臨時列表(或新數(shù)組)存儲去重后的元素;遍歷原始數(shù)組,對每個元素,檢查它是否已存在于臨時列表中;若不存在,則添加到臨時列表,若已存在則跳過;最后將臨時列表轉(zhuǎn)換為數(shù)組。代碼示例如下:
java取消自動換行復(fù)制
該方法的優(yōu)點是邏輯直觀,無需依賴 Set 集合的特性,缺點是存在雙重循環(huán),時間復(fù)雜度為 O (n2),當(dāng)元素數(shù)量較多(如超過 1000 個)時,效率會明顯下降,因此更適合小規(guī)模數(shù)據(jù)的去重。
方法三:先排序再去重(適合需排序的場景)
若業(yè)務(wù)中需要對數(shù)字進(jìn)行排序,可先通過排序算法將數(shù)組按升序或降序排列,排序后重復(fù)元素會相鄰排列,再通過一次遍歷即可刪除重復(fù)元素。該方法結(jié)合了排序與去重,適合既需去重又需排序的場景。
實現(xiàn)步驟:首先使用Arrays.sort()對原始數(shù)組進(jìn)行排序;然后創(chuàng)建新數(shù)組或列表,遍歷排序后的數(shù)組,僅保留與前一個元素不同的元素(即跳過重復(fù)元素)。代碼示例如下:
java取消自動換行復(fù)制
import java.util.Arrays;
public class RemoveDuplicatesAfterSort {
public static void main(String[] args) {
int[] originalArray = {7, 2, 3, 2, 7, 5, 3, 8};
// 1. 對數(shù)組排序(默認(rèn)升序)
Arrays.sort(originalArray);
// 2. 遍歷排序后的數(shù)組,去重
// 臨時變量存儲去重后的元素個數(shù)
int uniqueCount = 1;
for (int i = 1; i < originalArray.length; i++) {
// 若當(dāng)前元素與前一個元素不同,則為唯一元素
if (originalArray[i] != originalArray[uniqueCount - 1]) {
originalArray[uniqueCount] = originalArray[i];
uniqueCount++;
}
}
// 3. 截取數(shù)組,獲取去重后的結(jié)果
int[] uniqueArray = Arrays.copyOf(originalArray, uniqueCount);
// 輸出結(jié)果:[2, 3, 5, 7, 8](已排序且無重復(fù))
System.out.println(Arrays.toString(uniqueArray));
}
}
該方法的時間復(fù)雜度主要取決于排序步驟,Arrays.sort()采用的是雙軸快速排序算法,時間復(fù)雜度約為 O (n log n),后續(xù)遍歷去重的時間復(fù)雜度為 O (n),整體效率優(yōu)于手動遍歷去重。但缺點是會改變原始數(shù)組的順序(轉(zhuǎn)為排序后的順序),若需保留原始順序則不適用。

方法四:使用 Stream 流去重(Java 8 及以上,代碼最簡潔)
Java 8 引入的 Stream 流提供了便捷的數(shù)據(jù)處理能力,通過distinct()方法可直接實現(xiàn)元素去重,配合collect()方法還能將結(jié)果轉(zhuǎn)換為數(shù)組或列表,代碼簡潔且可讀性高,適合 Java 8 及以上版本的開發(fā)場景
實現(xiàn)步驟:將數(shù)組或集合轉(zhuǎn)換為 Stream 流;調(diào)用distinct()方法去重;通過collect()將流轉(zhuǎn)換為目標(biāo)數(shù)據(jù)結(jié)構(gòu)(如 List),若需數(shù)組則進(jìn)一步轉(zhuǎn)換。代碼示例如下:
j取消自動換行復(fù)制
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class RemoveDuplicatesWithStream {
public static void main(String[] args) {
int[] originalArray = {6, 3, 8, 3, 6, 2, 9, 2};
// 1. 數(shù)組轉(zhuǎn)Stream流,去重后轉(zhuǎn)為List
List<Integer> uniqueList = Arrays.stream(originalArray)
.boxed() // 基本類型轉(zhuǎn)包裝類
.distinct() // 去重
.collect(Collectors.toList());
// 2. 若需數(shù)組,可從List轉(zhuǎn)換
int[] uniqueArray = uniqueList.stream()
.mapToInt(Integer::intValue)
.toArray();
// 輸出結(jié)果:[6, 3, 8, 2, 9](Stream流默認(rèn)順序與原始數(shù)組一致)
System.out.println(Arrays.toString(uniqueArray));
}
}
該方法的優(yōu)點是代碼簡潔,一行鏈?zhǔn)秸{(diào)用即可完成去重,且distinct()方法內(nèi)部通過LinkedHashSet實現(xiàn),能保留元素的原始順序,時間復(fù)雜度約為 O (n)。但需注意,該方法依賴 Java 8 及以上版本,且對于大規(guī)模數(shù)據(jù),Stream 流的性能與 Set 集合相近,適合追求代碼簡潔性的場景。
四種方法各有優(yōu)缺點,實際開發(fā)中需根據(jù)場景選擇:若需簡單高效且不依賴版本,優(yōu)先選擇 Set 集合去重;若需保留原始順序且使用 Java 8+,推薦 Stream 流;若需同時排序,可采用先排序再去重的方式;若對集合類不熟悉或數(shù)據(jù)量小,手動遍歷去重更易理解。無論選擇哪種方法,核心思路都是通過 “判斷元素唯一性” 實現(xiàn)去重,開發(fā)者可根據(jù)數(shù)據(jù)規(guī)模、版本要求及順序需求靈活選擇。