Collections及Arrays相关操作

Collections & Arrays相关操作

(一)Collections:集合相关操作

  • 排序
  • 查找、替换
  • 同步控制(不推荐,需要线程安全的集合类型应该选择java.util.concurrent包下的并发集合)
1
2
3
4
5
6
7
8
9
10
ArrayList<Integer> list = new ArrayList<>();
list.add(-1);
list.add(3);
list.add(3);
list.add(-5);
list.add(7);
list.add(4);
list.add(-9);
list.add(-7);
System.out.println("原始集合: " + list);

1.排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
System.out.println("========================排序========================");

//反转集合: void reverse(List list);
Collections.reverse(list);
System.out.println("反转集合: " + list);

//随机排序: void shuffle(List list);
Collections.shuffle(list);
System.out.println("随机排序(每次运行结果不同): " + list );

//升序排序: void sort(List list);
Collections.sort(list);
System.out.println("升序排序: " + list);

//定制排序,由Comparator决定顺序: void sort(List list, Comparator c);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1); //降序
}
});
System.out.println("定制排序(降序): " + list);

//交换两个元素的位置: void swap(List list, int i, int j);
Collections.swap(list, 0, 1);
System.out.println("交换两个元素(0和1)位置: " + list);

//旋转集合: void rotate(List list, int distance);
//distance > 0: 将后distance个数前移
Collections.rotate(list, 3);
System.out.println("将后3个数前移: " + list);
//distance < 0: 将前distance个数后移
Collections.rotate(list, -3);
System.out.println("将前3个数后移: " + list);

2.查找/替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
System.out.println("========================查找/替换========================");

//二分查找(注意list必须有序): int binarrySearch(List list, Object key);
//返回下标从0开始,如果有多个匹配的,返回最先找到的那个
Collections.sort(list);
System.out.println("排序后数组: " + list);
int index = Collections.binarySearch(list, 3);
System.out.println("binarrySearch找3: " + index);

//根据自然顺序,返回最大的: int max(Collection c);
//int min(Collection c)同理
int max = Collections.max(list);
System.out.println("max返回: " + max);

//根据定制顺序,返回最大的: int max(Collection c, Comparator co);
//int min(Collection c, Comparator co)同理
int comparatorMax = Collections.max(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
System.out.println("定制max返回(逆序最大): " + comparatorMax);

//用指定元素填充集合: void fill(List list, Object obj);
Collections.fill(list, 0);
System.out.println("fill(用0替换全部元素)返回: " + list);

//统计元素出现次数: int frequency(Collection c, Object obj);
int frequency = Collections.frequency(list, 0);
System.out.println("frequency(0出现次数)返回: " + frequency);

//子集合第一次出现位置,如果没有则返回-1: int indexOfSubList(List list, List target);
int indexOfSub = Collections.indexOfSubList(list, Arrays.asList(1, 2, 3));
System.out.println("子数组([1,2,3])第一次出现位置: " + indexOfSub);

//用新元素替换老元素: boolean replaceAll(List list, Object old, Object new);
if (Collections.replaceAll(list, 0, 7)) {
System.out.println("用新元素(7)替换老元素(0): " + list);
}else {
System.out.println("replaceAll失败");
}

3.同步

  1. Collections提供了很多创建线程安全的集合的工厂方法,但是这些工厂方法效率极低,需要使用线程安全的集合还是先考虑J.U.C包下的并发集合
1
2
3
4
5
//由对应集合创建的线程安全集合
synchronizedCollection(Collection<T> c);
synchronizedList(List<T> l);
synchronizedMap(Map<K, V> m);
synchronizedSet(Set<T> s);
  1. Collections还提供了创建不可变(只读,如果修改则抛出UnsupportedOperationException集合的工厂方法(Xxx可以是List/Set/Map):
  • emptyXxx():空集合

    很多时候,返回emptyList要比直接返回null更安全,因为你不确定对方会不会单独对null进行判空处理

  • singletonXxx():单元素集合

  • unmodifiableXxx():不可变集合


(二)Arrays:数组相关操作

  • 排序:sort()
  • 查找:binarrySearch()
  • 比较:equals()
  • 填充:fill()
  • 转列表:asList()
  • 转字符串:toString()
  • 复制:copyOf()copyOfRange()
1
2
int[] a = { 1, 3, 2, 7, 6, 5, 4, 9 };
System.out.println("原始数组: " + Arrays.toString(a));

1.排序

1
2
3
4
5
6
7
8
9
10
11
12
System.out.println("========================排序========================");
//指定范围升序排列: void sort(int[] a, int fromIndex, int toIndex);
Arrays.sort(a, 0, 3);
System.out.println("指定范围(0 ~ 3)升序排列: " + Arrays.toString(a));

//并行升序排序: parallelSort(int[] a);同理

//升序排序: void sort(int[] a);
Arrays.sort(a);
System.out.println("升序排列后数组: " + Arrays.toString(a));

//并行升序排序: parallelSort(int[] a, int from, int to);同理

2.二分查找

1
2
3
4
5
System.out.println("========================查找========================");
//二分查找: int binarrySearch(int[] a, Object obj);
//数组必须是排序好的,同时如果有多个匹配的,返回第一个找到的
int index3 = Arrays.binarySearch(a, 3);
System.out.println("二分查找(3的下标): " + index3);

3.比较

1
2
3
4
5
6
7
8
9
System.out.println("========================比较========================");
//比较两数组是否相等: boolean equals(int[] a, int[] b);
//必须数组长度和元素顺序都相等,才是相等
int[] b = {1, 2, 3, 4, 5, 6, 9, 7};
int[] c = {1, 2, 3, 4, 5, 6, 7};
int[] d = {1, 2, 3, 4, 5, 6, 7, 8};
System.out.println("a = b ? " + Arrays.equals(a, b)); //false
System.out.println("a = c ? " + Arrays.equals(a, c)); //false
System.out.println("a = d ? " + Arrays.equals(a, d)); //false

4.填充

1
2
3
4
5
System.out.println("========================填充========================");
//填充: void fill(int[] a, Object obj);
Arrays.fill(b, 0);
//原数组b:[1, 2, 3, 4, 5, 6, 9, 7]
System.out.println("填充()后的数组b: " + Arrays.toString(b));

5.转列表:asList()不允许修改

public static <T> List<T> asList(T... a)

注意事项

(1).传入的必须是对象数组

Arrays.asList()泛型方法,传入的数组必须是对象变长参数列表(T...

如果传入的是基本类型数组,比如int[],由于asList()只支持对象变长参数列表,那么它会认为参数是这个基本类型数组,而不是基本类型数组内的对象,因为基本类型不是对象。

泛型不允许基本类型

1
2
3
4
5
int[] myArray = new int[]{1, 2, 3};
List list = Arrays.asList(myArray);
//被转化为List的是myArray这个对象
System.out.println(list.size() ); //输出:1
System.out.println(list.get(0) ); //输出:myArray的内存地址
(2).修改得到的集合会抛出异常

Arrays.asList()获得的集合进行修改——add()remove()clear()会抛出UnsupportedOperationException

原因

Arrays.asList()返回的不是java.util.ArrayList,而是java.util.Arrays的一个内部类java.util.Arrays$ArrayList,这个类没有实现add()/remove()/clear()

解决:将数组转为java.util.ArrayList!!!

List list = new ArrayList<>(Arrays.asList("a", "b", "c") );


6.转字符串

Arrays.toString(int[] a)


7.复制

  1. copyOf(boolean[] a, int len)

  2. copyOf(byte[] a, int len)

  3. copyOf(char[] a, int len)

  4. copyOf(double[] a, int len)

  5. copyOf(float[] a, int len)

  6. copyOf(int[] a, int len)

  7. copyOf(long[] a, int len)

  8. copyOf(short[] a, int len)

  9. copyOf(T[] a, int len)

  10. copyOfRange(T[] a, int from, int to)复制指定范围[from,to),下标从0开始,不包括to所在位置元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    System.out.println("========================复制========================");
    //复制对应长度的数组: int[] copyOf(int[] a, int len);
    int[] copy = Arrays.copyOf(a,6);
    System.out.println(Arrays.toString(copy));

    //复制指定范围[from,to): int[] copyOfRange(int[] a, int from, int to);
    //注意下标是从0开始的
    //注意,不包括to所在位置元素
    int[] copyOfRange = Arrays.copyOfRange(a, 1, 6);
    System.out.println(Arrays.toString(copyOfRange));
  11. copyOf(U[] original, int newLength, Class<? extends T[]> newType):复制指定长度的原数组,同时强制转换为指定的新的数组类型

1
2
3
4
5
6
7
8
9
10
11
//@param original 待复制数组
//@param newLength 副本长度
//@param newType 副本所属类(必须是数组类)
copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Arrays.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}

与之类似的有System.arraycopy(Object src, int srcPos, Object desc, int descPos, int length), 其中src是原数组, srcPos是原数组复制开始位置, desc是新数组, descPos是新数组覆盖开始位置, length是复制长度。作用是将原数组拷贝到指定数组:

1
2
3
4
5
int[] zero = {0, 0, 0, 0, 0};
int[] one = {1, 1, 1, 1, 1};
System.arraycopy(zero, 0, one, 0, 2);
System.out.println(Arrays.toString(one));
//[0, 0, 1, 1, 1]
-------------本文结束感谢您的阅读-------------

本文标题:Collections及Arrays相关操作

文章作者:DragonBaby308

发布时间:2019年08月10日 - 21:45

最后更新:2020年01月25日 - 13:43

原始链接:http://www.dragonbaby308.com/Collections-Arrays/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%