方案一:HashSet
方案二:HashMap
方案三:BitSet
利用HashSet去重:
public static void main(String[] args) {
removeRepeatPhoneBySet();
}
/**
* 根据HashSet去重
*/
public static void removeRepeatPhoneBySet() {
//构造手机号数据
List<String> phoneList = new ArrayList<>();
phoneList.add("18813458679");
phoneList.add("18813458679");
phoneList.add("18713458680");
phoneList.add("16613458681");
//利用HashSet去重
Set<String> phoneSet = new HashSet<>(phoneList);
System.out.println("去重前:" + phoneList);
System.out.println("去重后:" + new ArrayList<>(phoneSet));
}
输出:
去重前:[18813458679, 18813458679, 18713458680, 16613458681]
去重后:[18813458679, 16613458681, 18713458680]
利用HashMap去重:
/**
* 利用map去重
*/
public static void removeRepeatPhoneByMap() {
//构造手机号数据
List<String> phoneList = new ArrayList<>();
phoneList.add("18813458679");
phoneList.add("18813458679");
phoneList.add("18713458680");
phoneList.add("16613458681");
//利用map的key不能重复的特性进行去重
Map<String, String> phoneMap = new HashMap<>();
//遍历手机号集合,放到map中去
for (String s : phoneList) {
if (!phoneMap.containsKey(s)) {
phoneMap.put(s, s);
}
}
System.out.println("去重前:" + phoneList);
//再将map转为list集合
phoneList.clear();
phoneList.addAll(phoneMap.keySet());
System.out.println("去重后:" + phoneList);
}
输出:
去重前:[18813458679, 18813458679, 18713458680, 16613458681]
去重后:[18813458679, 16613458681, 18713458680]
可以看到以上两种方法都可以对手机号进行去重,但当手机号的数量达到千万甚至上亿级别时,以上两种方法十分消耗内存,可用性大打折扣。
利用BitSet进行去重:
/**
* 利用BitSet去重
*/
public static void removeRepeatPhoneByBitSet() {
//构造手机号数据
List<String> phoneList = new ArrayList<>();
phoneList.add("18813458679");
phoneList.add("18813458679");
phoneList.add("18713458680");
phoneList.add("16613458681");
phoneList.add("16613655809");
Map<String, BitSet> phoneMap = new HashMap<>();
for (String s : phoneList) {
/*
* 由于BitSet利用下标进行存储元素,下标为int型,11位手机号无法存下
* 所以可以截取前3位手机号作为key存储到map中去,后8位手机号存到BitSet中去
* 再将BitSet作为alue存到map中去
*/
BitSet bitSet = phoneMap.computeIfAbsent(s.substring(0, 3), k -> new BitSet());
bitSet.set(Integer.parseInt(s.substring(3)));
}
System.out.println("去重前:" + phoneList);
System.out.println("去重后:" + phoneMap);
}
输出:
去重前:[18813458679, 18813458679, 18713458680, 16613458681, 16613655809]
去重后:{187={13458680}, 166={13458681, 13655809}, 188={13458679}}
当手机号的前三位重复且后八位不重复时(166={13458681, 13655809}),那么BitSet中会有两个下标会返回true。
可以看到,利用BitSet的特性也可以对手机号进行去重,由于BitSet存储时,该元素即是下标,所以对内存的消耗非常小。