自增 list

  • 采用 Collections.sort() 方法的 list,不管是添加时 sort 还是添加完后再 sort,都很慢
    • 但是遍历时被如果被其他线程修改,可能会导致 modCount 异常
  • 采用 Collections.BinarySearch() 方法的 list,速度快一点
    • 但是遍历时被如果被其他线程修改,可能会导致 modCount 异常
  • CopyOnWriteArray 提供快照读功能,即迭代时 modCount 使用的是旧数组的;但是会写时复制,大量单独插入不适用
  • treeSet **同样数据量,treeSet 添加在 0.05m 左右; **add 时间效率高,且查找元素,是基于类似二分搜索树的结构,效率更高 ```java static List sortList = new ArrayList() {

    1. @Override
    2. public boolean add(Long o) {
    3. boolean ret = super.add(o);
    4. if (ret) {
    5. this.sort(Comparator.comparing(AdvancedMail::getId));
    6. }
    7. return ret;
    8. }

    };

    static List binaryList = new ArrayList() {

    1. @Override
    2. public boolean add(Long o) {
    3. int index = Collections.binarySearch(
    4. this, mail, Comparator.comparing(AdvancedMail::getId));
    5. if (index < 0) {
    6. index = ~index;
    7. }
    8. super.add(index, o);
    9. return true;
    10. }

    };

    static List arrayList = new ArrayList<>();

    static Set treeSet = new TreeSet<>();

    public static void main(String[] args) throws RunnerException {

    1. int size = 100000;
    2. List<Long> longs = readFromFile(new File("data.txt"), size);
    3. Stopwatch stopwatch = Stopwatch.createStarted();
    4. for (int i = 0; i < size; i++) {
    5. // 13s
    6. // sortList.add(longs.get(i));
    7. // 0.5s
    8. binaryList.add(longs.get(i));
    9. // 0.06s
    10. treeSet.add(longs.get(i));
    11. // 0.008s + 排序 约等于 13s
    12. arrayList.add(longs.get(i));
    13. arrayList.sort(Comparator.comparing(AdvancedMail::getId));
    14. }
    15. stopwatch.stop();
    16. System.out.println(stopwatch.elapsed(TimeUnit.MILLISECONDS));

    }

    public static boolean checkSame(List beforeList, List afterList) {

    1. beforeList.sort(Comparator.comparing(AdvancedMail::getId));
    2. if (afterList instanceof List) {
    3. List<Long> tempList = (ArrayList<Long>) afterList;
    4. for (int i = 0; i < beforeList.size(); i++) {
    5. if (!(beforeList.get(i).equals(tempList.get(i)))) {
    6. return false;
    7. }
    8. }
    9. } else if (afterList instanceof Set) {
    10. Set<Long> tempSet = (TreeSet<Long>) afterList;
    11. int i = 0;
    12. for (Long aLong : tempSet) {
    13. if (!beforeList.get(i).equals(aLong)) {
    14. return false;
    15. }
    16. i++;
    17. }
    18. }
    19. return true;

    }

  1. public static void writeText(File file, int size) {
  2. try (OutputStream outputStream = new FileOutputStream(file)) {
  3. for (int i = 0; i < size; i++) {
  4. outputStream.write(String.valueOf(ThreadLocalRandom.current().nextLong()).getBytes());
  5. if (i != size - 1) {
  6. outputStream.write(",".getBytes());
  7. }
  8. }
  9. } catch (Exception e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. public static List<Long> readFromFile(File file, int size) {
  14. List<Long> dataList = new ArrayList<>(size);
  15. try {
  16. List<String> contentList = Files.readAllLines(Paths.get(file.getName()));
  17. String str = contentList.get(0);
  18. String[] split = str.split(",");
  19. for (int i = 0; i < size; i++) {
  20. dataList.add(Long.parseLong(split[i]));
  21. }
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. return dataList;
  26. }
  1. ---
  2. <a name="yID9D"></a>
  3. ## 比较器创建
  4. - java8 提供比较器创建,下面是其中之一
  5. > public static _<_T, U extends Comparable_<_? super U_>> _Comparator_<_T_> _comparing (
  6. > _ _Function_<_? super T, ? extends U_> _keyExtractor) {}
  7. `Comparator.comparing(AdvancedMail::getId)` 表示按照 AdvancedMail#getId() 自然排序,类似生成了下面的 lambda
  8. ```java
  9. ((o1, o2) -> {
  10. if (o1.getId() > o2.getId()) {
  11. return 1;
  12. } else if (o1.getId().equals(o2.getId())) {
  13. return 0;
  14. } else {
  15. return -1;
  16. }
  17. })

如果需要自定义排序,则使用下面这个重载方法

public static <_T, U> Comparator<_T_> comparing( Function<_? super T, ? extends U_> keyExtractor, Comparator<_? super U_> _keyComparator)

将排序 lambda 进行书写类似


list分组

  • groupingBy 返回一个map,key 是 分组标志,value 是分组结果
    1. Map<String, List<Entrance>> collect = entrances.stream().collect(Collectors.groupingBy(Entrance::getFlag));
    2. collect.forEach((k,v)->{
    3. for (Entrance entrance1 : v) {
    4. if (entrance1.lock) {
    5. entrance1.needShow = true;
    6. return;
    7. }
    8. }
    9. });