是的,就是这么挫
代码经过测试的
贴下代码
package search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
public class LetterIndexer {
public static final String SEPARATOR = "|";
/**
* sourceList >> 服务器最新接口列表
*/
private ArrayList<String> sourceList = new ArrayList<String>();
/**
* targetList >> 目标列表,遍历后剩下的列表数据就是diff
*/
private ArrayList<String> targetList = new ArrayList<String>();
/**
* hashMap >> 存储字母在sourceList出现的区间
*/
private HashMap<String, String> hashMap = new HashMap<>();
/**
* 是否把sourceList下标为0的首字母存进HashMap
*/
private boolean isPutFirstLetterForSoureList = false;
public LetterIndexer(ArrayList<String> sourceList){
this.sourceList.addAll(sourceList);
this.targetList.addAll(sourceList); //相等是为了得到差异化文件,本次是初级接口,所以未判断接口是否更新
}
public void diff(ArrayList<String> localList) {
int size = sourceList.size();
if (size > 0) {
Collections.sort(sourceList);
initHashMap(size);
for (String session : localList) {
int[] array = getArray(session);
match(array, session);
}
}
}
/**
* 初始化HashMap
* @param size sourceList大小
*/
private void initHashMap(int size) {
String temp = sourceList.get(0).substring(0, 1);
int index = 0;
for (int i = 0; i < size; i ++) {
String firstLetter = sourceList.get(i).substring(0, 1);
if (!temp.equals(firstLetter)){
if (!isPutFirstLetterForSoureList) {
//sourceList首字母
hashMap.put(temp, index + SEPARATOR + (i - 1));
isPutFirstLetterForSoureList = true;
temp = firstLetter;
index = i;
continue;
}
hashMap.put(temp, index + SEPARATOR + (i - 1));
temp = firstLetter;
index = i;
}
}
//sourceList末字母
hashMap.put(temp, index + SEPARATOR + (size - 1));
}
/**
* 获取本地一个接口的首字母在sourceList的开始结束位置
* @param session 本地的一个接口
* @return
*/
private int[] getArray(String session){
Set<Entry<String, String>> entrySet = hashMap.entrySet();
for (Entry<String, String> entry : entrySet) {
if (entry.getKey().equals(session.substring(0, 1))) {
String[] str = entry.getValue().toString().split("\\|");
int[] array = new int[2];
array[0] = Integer.parseInt(str[0]);
array[1] = Integer.parseInt(str[1]);
return array;
}
}
return null;
}
/**
* 查询本地的一个接口是否存在sourceList中, 是则在targetList中移除
* @param str sourceList某字母区间
* @param letter 本地接口首字母
* @return
*/
private void match(int[] str, String session){
if (str == null) return;
int index = str[0];
int size = str[1];
for (int i = index; i < size; i ++) {
String temp = sourceList.get(i);
if (temp.equals(session)) {
targetList.remove(temp);
}
}
}
}
写完后才发现,我当初怎么那么傻,居然想到索引器这种鬼东西,明明 List 原生 API 就有提供去重方法removeAll()
然后说下差距吧