自增 list
- 采用
Collections.sort()
方法的 list,不管是添加时 sort 还是添加完后再 sort,都很慢- 但是遍历时被如果被其他线程修改,可能会导致 modCount 异常
- 采用
Collections.BinarySearch()
方法的 list,速度快一点- 但是遍历时被如果被其他线程修改,可能会导致 modCount 异常
- CopyOnWriteArray 提供快照读功能,即迭代时 modCount 使用的是旧数组的;但是会写时复制,大量单独插入不适用
treeSet **同样数据量,treeSet 添加在 0.05m 左右; **add 时间效率高,且查找元素,是基于类似二分搜索树的结构,效率更高 ```java static List
sortList = new ArrayList () { @Override
public boolean add(Long o) {
boolean ret = super.add(o);
if (ret) {
this.sort(Comparator.comparing(AdvancedMail::getId));
}
return ret;
}
};
static List
binaryList = new ArrayList () { @Override
public boolean add(Long o) {
int index = Collections.binarySearch(
this, mail, Comparator.comparing(AdvancedMail::getId));
if (index < 0) {
index = ~index;
}
super.add(index, o);
return true;
}
};
static List
arrayList = new ArrayList<>(); static Set
treeSet = new TreeSet<>(); public static void main(String[] args) throws RunnerException {
int size = 100000;
List<Long> longs = readFromFile(new File("data.txt"), size);
Stopwatch stopwatch = Stopwatch.createStarted();
for (int i = 0; i < size; i++) {
// 13s
// sortList.add(longs.get(i));
// 0.5s
binaryList.add(longs.get(i));
// 0.06s
treeSet.add(longs.get(i));
// 0.008s + 排序 约等于 13s
arrayList.add(longs.get(i));
arrayList.sort(Comparator.comparing(AdvancedMail::getId));
}
stopwatch.stop();
System.out.println(stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
public static boolean checkSame(List
beforeList, List afterList) { beforeList.sort(Comparator.comparing(AdvancedMail::getId));
if (afterList instanceof List) {
List<Long> tempList = (ArrayList<Long>) afterList;
for (int i = 0; i < beforeList.size(); i++) {
if (!(beforeList.get(i).equals(tempList.get(i)))) {
return false;
}
}
} else if (afterList instanceof Set) {
Set<Long> tempSet = (TreeSet<Long>) afterList;
int i = 0;
for (Long aLong : tempSet) {
if (!beforeList.get(i).equals(aLong)) {
return false;
}
i++;
}
}
return true;
}
public static void writeText(File file, int size) {
try (OutputStream outputStream = new FileOutputStream(file)) {
for (int i = 0; i < size; i++) {
outputStream.write(String.valueOf(ThreadLocalRandom.current().nextLong()).getBytes());
if (i != size - 1) {
outputStream.write(",".getBytes());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static List<Long> readFromFile(File file, int size) {
List<Long> dataList = new ArrayList<>(size);
try {
List<String> contentList = Files.readAllLines(Paths.get(file.getName()));
String str = contentList.get(0);
String[] split = str.split(",");
for (int i = 0; i < size; i++) {
dataList.add(Long.parseLong(split[i]));
}
} catch (IOException e) {
e.printStackTrace();
}
return dataList;
}
---
<a name="yID9D"></a>
## 比较器创建
- java8 提供比较器创建,下面是其中之一
> public static _<_T, U extends Comparable_<_? super U_>> _Comparator_<_T_> _comparing (
> _ _Function_<_? super T, ? extends U_> _keyExtractor) {}
`Comparator.comparing(AdvancedMail::getId)` 表示按照 AdvancedMail#getId() 自然排序,类似生成了下面的 lambda
```java
((o1, o2) -> {
if (o1.getId() > o2.getId()) {
return 1;
} else if (o1.getId().equals(o2.getId())) {
return 0;
} else {
return -1;
}
})
如果需要自定义排序,则使用下面这个重载方法
public static <_T, U> Comparator<_T_> comparing( Function<_? super T, ? extends U_> keyExtractor, Comparator<_? super U_> _keyComparator)
将排序 lambda 进行书写类似
list分组
- groupingBy 返回一个map,key 是 分组标志,value 是分组结果
Map<String, List<Entrance>> collect = entrances.stream().collect(Collectors.groupingBy(Entrance::getFlag));
collect.forEach((k,v)->{
for (Entrance entrance1 : v) {
if (entrance1.lock) {
entrance1.needShow = true;
return;
}
}
});