Collections工具类方法详解

1.sort(List), sort(List, Comparator)方法:对集合进行排序,列表中元素需要实现Comparable接口;前者使用Collection自然比较法,后者采用自定义的比较方法

源码:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
     list.sort(null);
}

public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
}

例:

public static void main (String args[]) {
        // 1.sort方法
        List list = new ArrayList();
        list.add("h");
        list.add("e");
        list.add("l");
        list.add("l");
        list.add("o");
        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);
    }

结果:

[h, e, l, l, o]
[e, h, l, l, o]
2.binarySearch(List,Object), binarySearch(List,Object, Comparator)方法:查找指定元素在集合中的位置,前者在算法比较时采用自然比较法,后者采用自定义的比较方法

源码:关于为什么要用不同的迭代方法可以看RandomAccess详解
算法思想: 先取集合中间的元素和指定元素进行比较,如果大于就说明指定元素在前半段,然后再拿前半段的中间元素和指定元素比较,以此循环直到找到index

public static <T>
    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
            return Collections.indexedBinarySearch(list, key);
        else
            return Collections.iteratorBinarySearch(list, key);
}
private static <T>
    int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
        int low = 0;
        int high = list.size()-1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            Comparable<? super T> midVal = list.get(mid);
            int cmp = midVal.compareTo(key);

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found
}
private static <T>
    int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
    {
        int low = 0;
        int high = list.size()-1;
        ListIterator<? extends Comparable<? super T>> i = list.listIterator();

        while (low <= high) {
            int mid = (low + high) >>> 1;
            Comparable<? super T> midVal = get(i, mid);
            int cmp = midVal.compareTo(key);

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found
}
private static <T> T get(ListIterator<? extends T> i, int index) {
        T obj = null;
        int pos = i.nextIndex();
        if (pos <= index) {
            do {
                obj = i.next();
            } while (pos++ < index);
        } else {
            do {
                obj = i.previous();
            } while (--pos > index);
        }
        return obj;
    }

例:

 // 3.binarySearch方法
        List list2 = new ArrayList();
        list2.add("h");
        list2.add("e");
        list2.add("l");
        list2.add("l");
        list2.add("o");
        System.out.println(Collections.binarySearch(list2, "o"));
        System.out.println(Collections.binarySearch(list2, "l"));

结果:可以看出,如果列表中如果有重复元素,返回的是第一个元素的位置

4
2
3.reverse()方法:反转集合中元素顺序

源码:

public static void reverse(List<?> list) {
        int size = list.size();
        if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
                swap(list, i, j);
        } else {
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator fwd = list.listIterator();
            ListIterator rev = list.listIterator(size);
            for (int i=0, mid=list.size()>>1; i<mid; i++) {
                Object tmp = fwd.next();
                fwd.set(rev.previous());
                rev.set(tmp);
            }
        }
    }

例:

// 2.reverse方法
List list1 = new ArrayList();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
System.out.println(list1);
Collections.reverse(list1);
System.out.println(list1);

结果:

[1, 2, 3, 4]
[4, 3, 2, 1]
4.shuffle(collection), shuffle(Collection,Random)方法:对集合进行随机排序,前者使用自然比较,后者采用自定义的Random

源码:通过swap方法及Random的随机数方法,对2个位置的元素随机交换

public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();

            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));

            // Dump array back into list
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }

例:

List list4 = new ArrayList();
        list4.add("h");
        list4.add("e");
        list4.add("l");
        list4.add("l");
        list4.add("o");
        System.out.println(list4);
        Collections.shuffle(list4);
        System.out.println(list4);

结果:

[h, e, l, l, o]
[l, l, e, h, o]
5.swap(Collection/Object[],int,int)方法:交换集合/数组中指定元素索引的位置

源码:

public static void swap(List<?> list, int i, int j) {
        // instead of using a raw type here, it's possible to capture
        // the wildcard but it will require a call to a supplementary
        // private method
        final List l = list;
        l.set(i, l.set(j, l.get(i)));
    }
private static void swap(Object[] arr, int i, int j) {
        Object tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

例:

List list3 = new ArrayList();
        list3.add("h");
        list3.add("e");
        list3.add("l");
        list3.add("l");
        list3.add("o");
        System.out.println(list3);
        Collections.swap(list3, 1,4);
        System.out.println(list3);

结果:

[h, e, l, l, o]
[h, o, l, l, e]
6.fill(Collection,Object)方法:用某个对象替换集合中所有元素

源码:

public static <T> void fill(List<? super T> list, T obj) {
        int size = list.size();

        if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
            for (int i=0; i<size; i++)
                list.set(i, obj);
        } else {
            ListIterator<? super T> itr = list.listIterator();
            for (int i=0; i<size; i++) {
                itr.next();
                itr.set(obj);
            }
        }
    }

例:

List list5 = new ArrayList();
        list5.add("h");
        list5.add("e");
        list5.add("l");
        System.out.println(list5);
        Collections.fill(list5, "a");
        System.out.println(list5);
    }

结果:

[h, e, l]
[a, a, a]
7.copy(List a,List b)方法:将集合b中的元素全部复制到a中,并且覆盖相应索引的元素

源码:b长度要小于等于a

public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        int srcSize = src.size();
        if (srcSize > dest.size())
            throw new IndexOutOfBoundsException("Source does not fit in dest");

        if (srcSize < COPY_THRESHOLD ||
            (src instanceof RandomAccess && dest instanceof RandomAccess)) {
            for (int i=0; i<srcSize; i++)
                dest.set(i, src.get(i));
        } else {
            ListIterator<? super T> di=dest.listIterator();
            ListIterator<? extends T> si=src.listIterator();
            for (int i=0; i<srcSize; i++) {
                di.next();
                di.set(si.next());
            }
        }
    }

例:

List listA = new ArrayList();
        listA.add("h");
        listA.add("e");
        listA.add("l");
        List listB = new ArrayList();
        listB.add("a");
        listB.add("a");
        System.out.println(listA);
        Collections.copy(listA, listB);
        System.out.println(listA);

结果:

[h, e, l]
[a, a, l]
8.min(Collection),min(Collection, Comparator), max(Collection),max(Collection, Comparator)方法:找出集合中最小/大的元素,前者使用Collection自然比较法,后者采用自定义的Comparator比较

源码:从第一个开始,一个一个地往后比较

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) < 0)
                candidate = next;
        }
        return candidate;
    }
    
public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
        if (comp==null)
            return (T)min((Collection) coll);

        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (comp.compare(next, candidate) < 0)
                candidate = next;
        }
        return candidate;
    }

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) > 0)
                candidate = next;
        }
        return candidate;
    }

public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
        if (comp==null)
            return (T)max((Collection) coll);

        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (comp.compare(next, candidate) > 0)
                candidate = next;
        }
        return candidate;
    }

例:

List list6 = new ArrayList();
        list6.add("h");
        list6.add("e");
        list6.add("l");
        list6.add("l");
        list6.add("o");
        System.out.println(Collections.min(list6));
        System.out.println(Collections.max(list6));

结果:

e
o
9.rotate(List, int) 方法:将集合中的元素向右移动指定位,超长的元素循环到元素的最前方,正数向右移,负数向左移

源码:
算法: 随机访问List的算法是用循环用原来位置上的元素替换新位置上的元素;链表算法是先取移位后不需要前置的元素的长度,1.将这部分元素进行翻转;2.将剩余部分元素进行翻转;3.整体进行翻转

public static void rotate(List<?> list, int distance) {
        if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
            rotate1(list, distance);
        else
            rotate2(list, distance);
    }

    private static <T> void rotate1(List<T> list, int distance) {
        int size = list.size();
        if (size == 0)
            return;
        distance = distance % size;
        if (distance < 0)
            distance += size;
        if (distance == 0)
            return;

        for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
            T displaced = list.get(cycleStart);
            int i = cycleStart;
            do {
                i += distance;
                if (i >= size)
                    i -= size;
                displaced = list.set(i, displaced);
                nMoved ++;
            } while (i != cycleStart);
        }
    }

    private static void rotate2(List<?> list, int distance) {
        int size = list.size();
        if (size == 0)
            return;
        int mid =  -distance % size;
        if (mid < 0)
            mid += size;
        if (mid == 0)
            return;

        reverse(list.subList(0, mid));
        reverse(list.subList(mid, size));
        reverse(list);
    }

例:

List list7 = new ArrayList();
        list7.add("h");
        list7.add("e");
        list7.add("l");
        list7.add("l");
        list7.add("o");
        System.out.println(list7);
        Collections.rotate(list7, 2);
        System.out.println(list7);

结果:

[h, e, l, l, o]
[l, o, h, e, l]
10.replaceAll(List,Object,Object)方法:替换指定元素为新元素,如果替换成功返回true否则返回false

源码:

public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) {
        boolean result = false;
        int size = list.size();
        if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) {
            if (oldVal==null) {
                for (int i=0; i<size; i++) {
                    if (list.get(i)==null) {
                        list.set(i, newVal);
                        result = true;
                    }
                }
            } else {
                for (int i=0; i<size; i++) {
                    if (oldVal.equals(list.get(i))) {
                        list.set(i, newVal);
                        result = true;
                    }
                }
            }
        } else {
            ListIterator<T> itr=list.listIterator();
            if (oldVal==null) {
                for (int i=0; i<size; i++) {
                    if (itr.next()==null) {
                        itr.set(newVal);
                        result = true;
                    }
                }
            } else {
                for (int i=0; i<size; i++) {
                    if (oldVal.equals(itr.next())) {
                        itr.set(newVal);
                        result = true;
                    }
                }
            }
        }
        return result;
    }

例:

List list8 = new ArrayList();
        list8.add("h");
        list8.add("e");
        list8.add("l");
        list8.add("l");
        list8.add("o");
        System.out.println(list8);
        System.out.println(Collections.replaceAll(list8, "l", "a"));
        System.out.println(list8);

结果:

[h, e, l, l, o]
true
[h, e, a, a, o]
11.indexOfSubList(List a,List b),lastIndexOfSubList(List a,List b)方法:查找b在a中首次出现位置的索引。

源码:使用嵌套for循环来查找内容。每当匹配到一致的元素时,开始新的一轮外层循环

public static int indexOfSubList(List<?> source, List<?> target) {
        int sourceSize = source.size();
        int targetSize = target.size();
        int maxCandidate = sourceSize - targetSize;

        if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
            (source instanceof RandomAccess&&target instanceof RandomAccess)) {
        nextCand:
            for (int candidate = 0; candidate <= maxCandidate; candidate++) {
                for (int i=0, j=candidate; i<targetSize; i++, j++)
                    if (!eq(target.get(i), source.get(j)))
                        continue nextCand;  // Element mismatch, try next cand
                return candidate;  // All elements of candidate matched target
            }
        } else {  // Iterator version of above algorithm
            ListIterator<?> si = source.listIterator();
        nextCand:
            for (int candidate = 0; candidate <= maxCandidate; candidate++) {
                ListIterator<?> ti = target.listIterator();
                for (int i=0; i<targetSize; i++) {
                    if (!eq(ti.next(), si.next())) {
                        // Back up source iterator to next candidate
                        for (int j=0; j<i; j++)
                            si.previous();
                        continue nextCand;
                    }
                }
                return candidate;
            }
        }
        return -1;  // No candidate matched the target
    }
    
public static int lastIndexOfSubList(List<?> source, List<?> target) {
        int sourceSize = source.size();
        int targetSize = target.size();
        int maxCandidate = sourceSize - targetSize;

        if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
            source instanceof RandomAccess) {   // Index access version
        nextCand:
            for (int candidate = maxCandidate; candidate >= 0; candidate--) {
                for (int i=0, j=candidate; i<targetSize; i++, j++)
                    if (!eq(target.get(i), source.get(j)))
                        continue nextCand;  // Element mismatch, try next cand
                return candidate;  // All elements of candidate matched target
            }
        } else {  // Iterator version of above algorithm
            if (maxCandidate < 0)
                return -1;
            ListIterator<?> si = source.listIterator(maxCandidate);
        nextCand:
            for (int candidate = maxCandidate; candidate >= 0; candidate--) {
                ListIterator<?> ti = target.listIterator();
                for (int i=0; i<targetSize; i++) {
                    if (!eq(ti.next(), si.next())) {
                        if (candidate != 0) {
                            // Back up source iterator to next candidate
                            for (int j=0; j<=i+1; j++)
                                si.previous();
                        }
                        continue nextCand;
                    }
                }
                return candidate;
            }
        }
        return -1;  // No candidate matched the target
    }

测试:

List<String> source = Arrays.asList("hello".split(""));
        List<String> targetA = Arrays.asList("el".split(""));
        List<String> targetB = Arrays.asList("aaaaaahe".split(""));
        List<String> targetC = Arrays.asList("ko".split(""));
        System.out.println(Collections.indexOfSubList(source, targetA));
        System.out.println(Collections.indexOfSubList(source, targetB));
        System.out.println(Collections.indexOfSubList(source, targetC));

结果:b需要是a的子集

1
-1
-1
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值