Collection [集合] & Collections [集合工具类]

标签: java 数据结构 集合

java.util.* 中的集合结构

在这里插入图片描述

Collection 类中定义的基本方法
// 对集合的基础操作:
int size();  // 获取元素个数
boolean isEmpty();  // 是否个数为 0
boolean contains(Object element);  // 是否包含指定元素
boolean add(E element);  // 添加元素,成功时返回 true
boolean remove(Object element);  // 删除元素,成功时返回 true
Iterator<E> iterator();  // 获取迭代器

// 操作整个集合的方法:
boolean containsAll(Collection<?> c); // 是否包含指定集合 c 的全部元素
boolean addAll(Collection<? extends E> c);  // 添加c中所有的元素,如果集合有改变就返回 true
boolean removeAll(Collection<?> c)  // 删除和c中一致的元素,如果集合有改变就返回 true
boolean retainAll(Collection<?> c)  // 取交集,如果集合有改变就返回 true
void clear();  // 删除所有元素

// 转换为数组的方法:
Object[] toArray();  // 返回一个包含集合中所有元素的数组
<T> T[] toArray(T[] a);  // 将集合中的元素转换为数组

// 在 JDK 8 以后,Collection 接口还提供了从集合获取连续的或者并行流:
Stream<E> stream();
Stream<E> parallelStream();
遍历 Collection 的几种方式:

for-each

Collection<Person> persons = new ArrayList<Person>();
for (Person person : persons) { 
    System.out.println(person.name);  
}

Iterator 迭代器

Collection<Person> persons = new ArrayList<Person>();
Iterator iterator = persons.iterator();
while (iterator.hasNext) { 
    System.out.println(iterator.next);  
}  

使用 aggregate operations 聚合操作

Collection<Person> persons = new ArrayList<Person>();
persons.stream().forEach(new Consumer<Person>() {  
        @Override  
        public void accept(Person person) {  
            System.out.println(person.name);  
        }  
}); 

使用 lambda 表达式对聚合操作简化

Collection<Person> persons = new ArrayList<Person>();
persons.stream().forEach(e -> System.out.println(e.name)); 

Collections

Collection 工具类

1、sort 对集合进行排序

List<String> c = Arrays.asList("l", "o", "v", "e");
System.out.println(c);
Collections.sort(c);
System.out.println(c);
/* 
运行结果为:
[l, o, v, e]
[e, l, o, v]   
*/
// 底层实现:
Arrays.sort

2、reverse() 反转集合中元素的顺序

List list = Arrays.asList("one two three four five six siven".split(" "));
System.out.println(list);
Collections.reverse(list);
System.out.println(list);
/*
运行结果为:
[one, two, three, four, five, six, siven]
[siven, six, five, four, three, two, one]
*/
// 底层实现:
// 长度小于 18 的将前后对应位置的元素交换,大于18的使用两个迭代器:
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);
}

3、shuffle(Collection) 对集合进行随机排序

List<String> c = Arrays.asList("l", "o", "v", "e");
System.out.println(c);
Collections.shuffle(c);
System.out.println(c);

/*
运行结果为:
[l, o, v, e]
[l, v, e, o]
[o, v, e, l]
*/
// 底层实现:
// 使用一个 随机数 Random , 对数组数据进行随机交换
// List -> Array --Iterator--> List 
for (int i=size; i>1; i--)
  swap(arr, i-1, rnd.nextInt(i));

4、fill(List list,Object o) 用对象o替换集合list中的所有元素

List<String> c = Arrays.asList("l", "o", "v", "e");
System.out.println(c);
Collections.fill(c, "wtf");
System.out.println(c);

/*
运行结果为:
[wtf, wtf, wtf, wtf]
*/
// 底层实现:
// 数组大小小于 25 时 使用
list.set(index, obj);
// 数组大小大于 25 时 使用
ListIterator<? super T> itr = list.listIterator();
for (int i=0; i<size; i++) {
  itr.next();
  itr.set(obj);
}

5、copy(List m,List n) 将集合n中的元素全部复制到m中,并且覆盖相应索引的元素

List<String> c = Arrays.asList("l", "o", "v", "e");
List<String> d = Arrays.asList("copy", "copy");
Collections.copy(c, d);
System.out.println(c);
/*
运行结果为:
[copy, copy, v, e]
*/
// 底层实现:
// 数组大小小于 10 时 使用
list.set(index, obj);
// 数组大小大于 10 时 使用
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());
}

6、min(Collection),min(Collection,Comparator) 前者采用Collection内含自然比较法,后者采用Comparator进行比较

// 底层实现: 在迭代器中依次使用 Comparable 接口中的 compareTo() 方法进行比较
// 时间复杂度: O(n)
// 也可以手动指定相应的 Comparator
// List<String> c; 以下两个使用是等同的
Collections.min(c);
Collections.min(c, String::compareTo);

max() 方法同理

7、indexOfSubList(List list,List subList) 查找 subList 在 list 中首次出现位置的索引

List<String> c = Arrays.asList("l", "o", "o", "o", "o", "v", "e");
List<String> e = Arrays.asList("o", "v");
int index = Collections.indexOfSubList(c, e);
System.out.println(index);
/*
运行结果为: 4
*/
// 底层实现:
// 数组大小小于 35 时 使用 两层循环实现
for()
  for()
// 数组大小大于 35 时 使用 迭代器进行两层循环

// 时间复杂度: O(n^2)
    
lastIndexOfSubList() 方法同理

8、rotate(List list, int m) 循环右移 n 个元素。负数向左移动,正数向右移动

List<String> c = Arrays.asList("l", "o", "v", "e");
Collections.rotate(c, 1);
System.out.println(c);
/*
运行结果为: 
[e, l, o, v]
*/
// 底层实现:
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);
}

9、swap(List list,int i,int j) 交换集合中指定元素索引的位置

List<String> c = Arrays.asList("l", "o", "v", "e");
Collections.swap(c, 1, 2);
System.out.println(c);
/*
运行结果为: 
  [l, v, o, e]
*/
// 底层实现:
final List l = list;
l.set(i, l.set(j, l.get(i)));

10、binarySearch(Collection,Object) 查找指定集合中的元素,返回所查找元素的索引(二分查找)

List<String> c = Arrays.asList("l", "o", "v", "e");
int index = Collections.binarySearch(c, "o");
System.out.println(index);
/*
运行结果为: 
  1
*/
// 底层实现: 
// 数据量小于 5000 的, 使用普通二分查找
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
}
// 数据量大于 5000 的, 使用迭代器二分查找
private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
    int low = 0;
    int high = l.size()-1;
    ListIterator<? extends T> i = l.listIterator();
    while (low <= high) {
        int mid = (low + high) >>> 1;
        T midVal = get(i, mid);
        int cmp = c.compare(midVal, 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
}

11、replaceAll(List list,Object old,Object new) 批量替换元素为某元素, 替换的值存在返回true,反之返回false

List<String> c = Arrays.asList("l", "o", "v", "e");
boolean result = Collections.replaceAll(c, "o", "s");
System.out.println(result + "-" +c);
/*
运行结果为: 
true-[l, s, v, e]
*/
// 底层实现: 
// 数据量小于 11 的, 使用
list.set();
// 数据量大于 11 的, 使用
iterator.set();

12、 设置不可变集合

// 以下这些实例都是不可变的,对其进行操作会抛出 UnsupportedOperationException()
/**
	优势: ArrayList 的默认大小是 10 , 如果我们需要只存储一个对象的 List, 并且只用一次, 那么该方案会更省内存
*/
/*
 * 空的 list/set
 */
List emptyList = Collections.emptyList();
Set set = Collections.emptySet();

/*
 * 返回一个只包含一个对象的 List
 */
List<String> singleton = Collections.singletonList("test");

/*
 * 返回一个包含指定对象的 List
 */
List<String> unmodifiable = Collections.unmodifiableList(Arrays.asList("l","o","v","e"));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值