标签:
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"));