Colletion的一些api

Colletion的一些api
Collection工具类
现在已经实现List接口的实现类有:

AbstractList, AbstractSequentialList(抽象类) 
ArrayList,LinkedList, Stack, Vector(常用)
AttributeList,CopyOnWriteArrayList,RoleList, RoleUnresolvedList

void swap(List list, int i , int j)//交换两个索引位置的元素
swap方法源码:

@SuppressWarnings({"rawtypes", "unchecked"})
    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)));
    }

swap方法很简单,
1.l.get(i):获取下标i对应的元素
2.l.set(j, l.get(i)) 将下标i对应的元素付给下标为j的元素,并j原来的元素返回
3.l.set(i, l.set(j, l.get(i)))最后将返回的j元素原来的值赋给下标为i的元素

void reverse(List list)//反转
reverse方法源码:

private static final int REVERSE_THRESHOLD        =   18;
@SuppressWarnings({"rawtypes", "unchecked"})
    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);
            }
        }
}

从源码中我们可以看到,reverse()方法支持传入List类型(List只是一个接口),
对于reverse()方法先获取list的size,如果list的size小于18,或者实现了RandomAccess(随机读写接口),会通过调用swap方法将前后的元素对调
如果不符合要求上面两铬条件的一条,则分别生成指针在初始和末尾的两个迭代器,通过tmp这个中间变量,将前后元素对调
void rotate(List list, int distance)/旋转。当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面。

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);//将位置旋转,并将被替换的元素赋给displaced
            nMoved ++;
        } while (i != cycleStart);
    }
}

如果元素数量少,或者实现了随机读取接口执行rotate1方法,先将传入的distance对list长度取模,如果为负数,则将distance加上list长度,转换为相应的正数,然后是一个for循环嵌套一个do-while循环。
For循环中的判断条件为nMoved != size 也就是说,只有所有元素都调换了一遍之后,循环才会结束。
里层为do-while循环,
首先将i位置的元素旋转到他该到的位置
1.确定元素要旋转到的位置 i += distance;if (i >= size) i -= size;
2.将其替换,并获取被替换的值 displaced = list.set(i, displaced);
3.一个元素已经旋转到指定位置 nMoved+1
4.判断while条件,while(i != cycleStart)
//如果distance和size是倍数关系,在未完全旋转时while会结束,继续执行for循环,如果distance与size不是倍数关系,则在while循环中进行全部旋转for循环内的语句只走一次

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);
}

对于distance的处理rotate1与rotate2是不同的,
1.首先求出mid值,mid代表的是要旋转到第一位的元素
2.然后对(0,mid)做翻转,再对(mid,size)做翻转,最后将整个list做翻转,就得到了旋转后的结果。
//至于为啥我暂时也搞不清楚

int binarySearch(List list, Object key)
//对List进行二分查找,返回索引,注意List必须是有序的
int max(Collection coll)
//根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll)
int max(Collection coll, Comparator c)
//根据定制排序,返回最大元素,排序规则由Comparatator类控制。类比int min(Collection coll, Comparator c)
void fill(List list, Object obj)
//用指定的元素代替指定list中的所有元素。
int frequency(Collection c, Object o)
//统计元素出现次数
int indexOfSubList(List list, List target)
//统计target在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target).
boolean replaceAll(List list, Object oldVal, Object newVal)
// 用新元素替换旧元素
Array的常用api
排序 : sort()
查找 : binarySearch()
比较: equals()
填充 : fill()
转列表: asList()
转字符串 : toString()
复制: copyOf()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值