1. 程式人生 > >第三十六講 集合框架工具類

第三十六講 集合框架工具類

Collections工具類

Collections類概述

針對集合操作的工具類,裡面的方法都是靜態的,可以對集合進行排序、二分查詢、反轉、混排等。

Collection和Collections的區別

Collection是單列集合的頂層介面,有子介面List和Set;而Collections是針對集合操作的工具類,有對集合進行排序和二分查詢等方法。

Collections類的常用方法

對List集合排序

public static <T extends Comparable<? super T>> void sort(List<T> list)

方法根據元素的自然順序對指定列表按升序進行排序,列表中的所有元素都必須實現Comparable介面。

package cn.liayun.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CollectionsSimple {

	public static void main(String[] args) {
		methodDemo();
	}

	public static void methodDemo() {
		List<
String>
list = new ArrayList<String>(); list.add("abce"); list.add("z"); list.add("hehe"); list.add("nba"); System.out.println(list); //對list排序,自然排序。使用的是元素的CompareTo方法 Collections.sort(list); System.out.println(list); } }

以上是使用Collections類中的sort()方法對List集合進行排序,而且使用的是自然排序。但現在我們想要按照字串的長度進行排序,那又該如何做呢?這時需要用到下面的方法,根據指定比較器產生的順序對指定列表進行排序。此列表內的所有元素都必須可使用指定比較器相互比較。

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

很顯然,這時我們需要自定義一個比較器,使得比較是按照字串的長度來排序的。

package cn.liayun.comparator;

import java.util.Comparator;

public class ComparatorByLength implements Comparator<String> {

	@Override
	public int compare(String o1, String o2) {
		int temp = o1.length() - o2.length();
		return temp == 0 ? o1.compareTo(o2) : temp;
	}

}

測試Demo為:

package cn.liayun.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import cn.liayun.comparator.ComparatorByLength;

public class CollectionsSimple {

	public static void main(String[] args) {
		methodDemo();
	}

	public static void methodDemo() {
		List<String> list = new ArrayList<String>();
		list.add("abce");
		list.add("z");
		list.add("hehe");
		list.add("nba");
		
		System.out.println(list);
		//對list排序,自然排序。使用的是元素的CompareTo方法
//		Collections.sort(list);
		Collections.sort(list, new ComparatorByLength());
		System.out.println(list);
	}

}

逆序

方法宣告 功能描述
public static <T> Comparator<T> reverseOrder() 返回一個比較器,它強行逆轉實現了Comparable介面的物件Collection的自然順序
public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) 返回一個比較器,它強行逆轉指定比較器的順序

下面分別對以上兩個方法進行案例演示。我們首先按照字串的自然順序排序。

package cn.liayun.collections;

import java.util.TreeSet;

public class CollectionsSimple {

	public static void main(String[] args) {
		orderDemo();
	}
	
	public static void orderDemo() {
		TreeSet<String> set = new TreeSet<String>();
		set.add("abcde");
		set.add("aaa");
		set.add("k");
		set.add("cc");
		
		System.out.println(set);
	}

}

接下來,我們要反轉其自然排序。

package cn.liayun.collections;

import java.util.Collections;
import java.util.TreeSet;

public class CollectionsSimple {

	public static void main(String[] args) {
		orderDemo();
	}
	
	public static void orderDemo() {
		TreeSet<String> set = new TreeSet<String>(Collections.reverseOrder());
		set.add("abcde");
		set.add("aaa");
		set.add("k");
		set.add("cc");
		
		System.out.println(set);
	}

}

當然了,我們也可以使用比較器來做。首先我們定義一個反轉字串的自然順序的比較器,然後再呼叫此比較器。

package cn.liayun.collections;

import java.util.Comparator;
import java.util.TreeSet;

public class CollectionsSimple {

	public static void main(String[] args) {
		orderDemo();
	}
	
	public static void orderDemo() {
		Comparator<String> comparator = new Comparator<String>() {
			
			@Override
			public int compare(String o1, String o2) {
				return o2.compareTo(o1);
			}
		};
		
		TreeSet<String> set = new TreeSet<String>(comparator);
		set.add("abcde");
		set.add("aaa");
		set.add("k");
		set.add("cc");
		
		System.out.println(set);
	}

}

再來看第二個方法。我們首先定義一個按照字串的長度排序的比較器,接著按照字串的長度排序。

package cn.liayun.collections;

import java.util.Comparator;
import java.util.TreeSet;

public class CollectionsSimple {

	public static void main(String[] args) {
		orderDemo();
	}
	
	public static void orderDemo() {
		Comparator<String> comparator = new Comparator<String>() {
			
			@Override
			public int compare(String o1, String o2) {
				int temp = o1.length() - o2.length();
				return temp == 0 ? o1.compareTo(o2) : temp;
			}
		};
		
		TreeSet<String> set = new TreeSet<String>(comparator);
		set.add("abcde");
		set.add("aaa");
		set.add("k");
		set.add("cc");
		
		System.out.println(set);
	}

}

最後,我們反轉其順序:

package cn.liayun.collections;

import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;

public class CollectionsSimple {

	public static void main(String[] args) {
		orderDemo();
	}
	
	public static void orderDemo() {
		Comparator<String> comparator = new Comparator<String>() {
			
			@Override
			public int compare(String o1, String o2) {
				int temp = o1.length() - o2.length();
				return temp == 0 ? o1.compareTo(o2) : temp;
			}
		};
		
		TreeSet<String> set = new TreeSet<String>(Collections.reverseOrder(comparator));
		set.add("abcde");
		set.add("aaa");
		set.add("k");
		set.add("cc");
		
		System.out.println(set);
	}

}

獲取集合中的最大元素

方法宣告 功能描述
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 根據元素的自然順序,返回給定Collection的最大元素
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) 根據指定比較器產生的順序,返回給定Collection的最大元素

下面分別對以上兩個方法進行案例演示,先來看第一個方法。

package cn.liayun.collections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

public class CollectionsSimple {

	public static void main(String[] args) {
		Collection<String> coll = new ArrayList<String>();
		coll.add("abcd");
		coll.add("aa");
		coll.add("z");
		coll.add("nba");
		
		String max = Collections.max(coll);
		System.out.println("max = " + max);
	}
	
}

如果說現在要讓我們自己模擬一個獲取集合最大值的功能,那又該怎麼做呢?直接貼出程式碼如下:

/**
 * 模擬一個獲取集合最大值的功能
 */
public static <T extends Object & Comparable<? super T>> T getMax(Collection<? extends T> coll) {
	Iterator<? extends T> it = coll.iterator();
	//1,定義變數,記錄容器中的其中一個。
	T max = it.next();
	//2,遍歷容器中所有的元素。
	while (it.hasNext()) {
		T temp = it.next();
		//3,在遍歷過程中進行比較,只要比變數中的值大,用變數記錄下來,就哦了。
		if (temp.compareTo(max) > 0) {
			max = temp;
		}
		
	}
	return max;
}

我們檢視Java原始碼,發現它寫的和我們寫的一模一樣。
再來看第二個方法。首先,我們先自定義一個按照字串的長度排序的比較器。

package cn.liayun.comparator;

import java.util.Comparator;

public class ComparatorByLength implements Comparator<String> {

	@Override
	public int compare(String o1, String o2) {
		int temp = o1.length() - o2.length();
		return temp == 0 ? o1.compareTo(o2) : temp;
	}

}

然後再根據此比較器的排序獲取集合中的最大元素。

package cn.liayun.collections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import cn.liayun.comparator.ComparatorByLength;

public class CollectionsSimple {

	public static void main(String[] args) {
		Collection<String> coll = new ArrayList<String>();
		coll.add("abcd");
		coll.add("aa");
		coll.add("z");
		coll.add("nba");
		
		String max = Collections.max(coll, new ComparatorByLength());
		System.out.println("max = " + max);
	}
	
}

將非同步集合轉成同步集合

Collections還有一個可以將非同步集合轉成同步集合的方法,如下:

同步集合 synchronized集合(非同步的集合)

Arrays工具類

Arrays類概述

此類包含用來運算元組(比如排序和搜尋)的各種方法。此類還包含一個允許將陣列作為列表來檢視的靜態工廠。

Arrays類的常用方法

方法宣告 功能描述
public static <T> List<T> asList(T... a) 可以從Array轉換成List,也可以作為其他集合型別構造器的引數
public static void sort(...) 對整個陣列或者陣列的一部分進行排序。也可以使用此方法用給定的比較器對物件陣列進行排序
public static String toString(...) 列印陣列的內容

陣列轉成集合

將陣列轉換為集合,使用的方法為:

public static <T> List<T> asList(T... a):返回一個受指定陣列支援的固定大小的列表
package cn.liayun.arrays;

import java.util.Arrays;
import java.util.List;

public class ArraysSimple {

	public static void main(String[] args) {
		String[] strs = {"abc", "haha", "nba", "zz"};
		List<String> list = Arrays.asList(strs);
//		list.add("qq");//java.lang.UnsupportedOperationException,注意,不能使用集合的增刪方法,不能改變集合的長度。
		System.out.println(list.contains("nba"));
	}

}

那麼問題就來了,把陣列變成List集合有什麼好處? 可以使用集合的思想和方法來運算元組中的元素。但要注意,將陣列變成集合,不可以使用集合的增刪方法,因為陣列的長度是固定的。可以使用集合的諸如contains()、get()、indexOf()、subList()等等方法,如果你增刪,那麼會產生UnsupportedOperationException異常。
再看下面一段程式碼,試著執行一下,看看會輸出什麼結果。

package cn.liayun.arrays;

import java.util.Arrays;
import java.util.List;

public class ArraysSimple {

	public static void main(String[] args) {
		int[] arr = {45, 23, 78, 11, 99};
		List list = Arrays.asList(arr);
		System.out.println(list);
	}

}

此時將會輸出[[[email protected]]類似結果,以上程式碼沒有使用泛型,使用泛型應是如此。

package cn.liayun.arrays;

import java.util.Arrays;
import java.util.List;

public class ArraysSimple {

	public static void main(String[] args) {
		int[] arr = {45, 23, 78, 11, 99};
		List<int[]> list = Arrays.asList(arr);
		System.out.println(list);
	}

}

如果將上面的程式碼修改為如下。

package cn.liayun.arrays;

import java.util.Arrays;
import java.util.List;

public class ArraysSimple {

	public static void main(String[] args) {
		Integer[] arr = {45, 23, 78, 11, 99};
		List<Integer> list = Arrays.asList(arr);
		System.out.println(list);
	}

}