• 7.8 操作集合的工具类:Collections


    一、排序操作

    Collections提供了如下常用类方法用于对List集合进行排序:
    ★void reverse(List list):反转指定的List集合中的元素顺序。
    ★void shuffle(List list):对Lsit集合中的元素进行随机排序(shuffle方法模仿了”洗牌“动作)。
    ★void sort(List list):根据元素的自然顺序对指定集合元素按升序进行排序。
    ★void sort(List list,Comparator compare):根据指定Comparator产生顺序对List集合进行排序。
    ★void swap(List list,int i,int j):交换List集合中的索引i处和索引j处的元素。
    ★void rotate(Lsit list,int distance):当distance为整数时,将list集合后distance个元素”整体“移到前面;当distance为负数时,将list集合的前distance个元素整体移到后面。该方法不会改变集合的长度。
    下面程序示范了利用Collections工具类来操作list集合:

    import static java.util.Collections.*;
    import java.util.ArrayList;
    public class SortTest 
    {
    	public static void main(String[] args) 
    	{
    		var nums=new ArrayList();
    		nums.add(2);
    		nums.add(-5);
    		nums.add(3);
    		nums.add(0);
    		//原始排序
    		System.out.println(nums);//[2, -5, 3, 0]
    		//将list集合反转排序
    		reverse(nums);
    		System.out.println(nums);//[0, 3, -5, 2]
    		//按照List集合元素的自然顺序排序,调用元素Comparable接口中的caompreTo()方法
    		sort(nums);
    		System.out.println(nums);//[-5, 0, 2, 3]
    		//随机排序
    		shuffle(nums);
    		System.out.println(nums);//[-5, 3, 0, 2]
    	}
    }
    

    上面程序示范了Collection类常用排序操作。下面是一个梭哈柚子来演示List集合、Collection工具类的强大功能。

    import java.util.*;
    public class ShowHand
    {
    	// 定义该游戏最多支持多少个玩家
    	private final int PLAY_NUM = 5;
    	// 定义扑克牌的所有花色和数值.
    	private String[] types = {"方块", "草花", "红心", "黑桃"};
    	private String[] values = {"2", "3", "4", "5",
    		"6", "7", "8", "9", "10",
    		"J", "Q", "K", "A"};
    	// cards是一局游戏中剩下的扑克牌
    	private List<String> cards = new LinkedList<>();
    	// 定义所有的玩家
    	private String[] players = new String[PLAY_NUM];
    	// 所有玩家手上的扑克牌
    	private List<String>[] playersCards = new List[PLAY_NUM];
    
    	/**
    	 * 初始化扑克牌,放入52张扑克牌,
    	 * 并且使用shuffle方法将它们按随机顺序排列
    	 */
    	public void initCards()
    	{
    		for (var i = 0; i < types.length; i++)
    		{
    			for (var j = 0; j < values.length; j++)
    			{
    				cards.add(types[i] + values[j]);
    			}
    		}
    		// 随机排列
    		Collections.shuffle(cards);
    	}
    	/**
    	 * 初始化玩家,为每个玩家分派用户名。
    	 */
    	public void initPlayer(String... names)
    	{
    		if (names.length > PLAY_NUM || names.length < 2)
    		{
    			// 校验玩家数量,此处使用异常机制更合理
    			System.out.println("玩家数量不对");
    			return;
    		}
    		else
    		{
    			// 初始化玩家用户名
    			for (var i = 0; i < names.length; i++)
    			{
    				players[i] = names[i];
    			}
    		}
    	}
    	/**
    	 * 初始化玩家手上的扑克牌,开始游戏时每个玩家手上的扑克牌为空,
    	 * 程序使用一个长度为0的LinkedList来表示。
    	 */
    	public void initPlayerCards()
    	{
    		for (var i = 0; i < players.length; i++)
    		{
    			if (players[i] != null && !players[i].equals(""))
    			{
    				playersCards[i] = new LinkedList<String>();
    			}
    		}
    	}
    	/**
    	 * 输出全部扑克牌,该方法没有实际作用,仅用作测试
    	 */
    	public void showAllCards()
    	{
    		for (var card : cards )
    		{
    			System.out.println(card);
    		}
    	}
    	/**
    	 * 派扑克牌
    	 * @param first 最先派给谁
    	 */
    	public void deliverCard(String first)
    	{
    		// 调用Arrays工具类的binarySearch()方法,   报错空指针异常
    		// 查询出指定元素在数组中的索引
    		int firstPos=6;
    		for(int i=0;i<players.length;i++)
    		{
    			if(players[i].equals(first))
    			{
    				firstPos=i;
    				break;
    			}
    		}	
    		System.out.println("系统发牌中...");
    		
    //		var firstPos = Arrays.binarySearch(players, first);
    		// 依次给位于该指定玩家之后的每个玩家派扑克牌
    		for (var i = firstPos; i < PLAY_NUM; i++)
    		{
    			if (players[i] != null)
    			{
    				playersCards[i].add(cards.get(0));
    				cards.remove(0);
    			}
    		}
    		// 依次给位于该指定玩家之前的每个玩家派扑克牌
    		for (var i = 0; i < firstPos; i++)
    		{
    			if (players[i] != null)
    			{
    				playersCards[i].add(cards.get(0));
    				cards.remove(0);
    			}
    		}
    	}
    	/**
    	 * 输出玩家手上的扑克牌
    	 * 实现该方法时,应该控制每个玩家看不到别人的第一张牌,但此处没有增加该功能
    	 */
    	public void showPlayerCards()
    	{
    		for (var i = 0; i < PLAY_NUM; i++)
    		{
    			// 当该玩家不为空时
    			if (players[i] != null)
    			{
    				// 输出玩家
    				System.out.print(players[i] + " : " );
    				// 遍历输出玩家手上的扑克牌
    				for (var card : playersCards[i])
    				{
    					System.out.print(card + "	");
    				}
    			}
    			System.out.print("
    ");
    		}
    	}
    	public static void main(String[] args)
    	{
    		var sh = new ShowHand();
    		sh.initPlayer("电脑玩家", "孙悟空");
    		sh.initCards();
    		sh.initPlayerCards();
    		// 下面测试所有扑克牌,没有实际作用
    		sh.showAllCards();
    		System.out.println("---------------");
    		// 下面从"孙悟空"开始派牌
    		sh.deliverCard("孙悟空");
    		sh.showPlayerCards();
    //		/*
    //		这个地方需要增加处理:
    //		1.牌面最大的玩家下注.
    //		2.其他玩家是否跟注?
    //		3.游戏是否只剩一个玩家?如果是,则他胜利了。
    //		4.如果已经是最后一张扑克牌,则需要比较剩下玩家的牌面大小.
    //		*/
    //		// 再次从"电脑玩家"开始派牌
    		sh.deliverCard("电脑玩家");
    		sh.showPlayerCards();
    		sh.deliverCard("孙悟空");
    		sh.showPlayerCards();
    	}
    }
    

    二、查找和替换功能

    Collection还提供了如下常用查找、替换元素的类方法
    ★int binarySearch(List list,Object key):使用二分法搜索指定List集合,以获取指定对象在List集合中的索引。如果该方法可以正常工作,则必须保证List元素以及处于有序状态。
    ★Object max(Collection coll):更具元素自然排序,返回给定集合中的最大元素。
    ★Object max(Collection coll,Comparator compare):根据Comparator指定顺序,返回给定集合中的最大元素。
    ★Object min(Collection coll):更具元素自然排序,返回给定集合中的最小元素。
    ★Object min(Collection coll,Comparator compare):根据Comparator指定顺序,返回给定集合中的最小元素。
    ★void fill(List list,Object obj):使用指定元素obj替换指定List集合中的所有元素。
    ★int frequency(Collection c,Object o):返回指定集合中指定元素出现的次数。
    ★int indexOfSubList(List source,List target):返回子List对象在父List对象中第一次出现的位置索引;如果父List对象中没有出现这样的子List,则返回-1。
    ★int lastIndexOfSubList(List source,List target):返回子List对象在父List对象中最后一次出现的位置索引;如果父List对象中没有出现这样的子List,则返回-1。
    ★boolean repalceAll(List list,Object oldVal,Object newVal):使用一个新值newVal替换List对象的所有旧值oldVal。
    Collections工具类的用法:

    import java.util.ArrayList;
    import java.util.Collections;
    public class SearchTest 
    {
    	public static void main(String[] args) 
    	{
    		var nums=new ArrayList();
    		nums.add(2);
    		nums.add(-5);
    		nums.add(3);
    		nums.add(0);
    		System.out.println(nums);//[2, -5, 3, 0]
    		//最大元素
    		System.out.println(Collections.max(nums));//3
    		//最小元素
    		System.out.println(Collections.min(nums));//-5
    		//将nums中的0使用1代替
    		Collections.replaceAll(nums,0,1);
    		System.out.println(nums);//[2, -5, 3, 1]
    		//判断-5在List集合中出现的次数,返回0
    		System.out.println(Collections.frequency(nums,-5));//1
    
    
    		//对nums自然排序
    		Collections.sort(nums);
    		System.out.println(nums);//[-5, 1, 2, 3]
    		//使用二分法查找元素
    		System.out.println(Collections.binarySearch(nums,2));//2
    	}
    }
    

    三、同步控制

    Collections类中提供了多个synchronizedXxx()方法,该方法可以将集合包装成线程同步的集合,从而解决多线程并发访问集合时的线程安全问题。
    Java中常用集合框架中的实现类HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap和treeMap都是线程不安全的。如果多个线程访问它们,而且有超过一个的线程试图修改它们,则它们存在线程安全问题。Collections提供了多个类方法可以把它们包装成线程同步的集合。

    
    import java.util.*;
    public class SynchronizedTest
    {
    	public static void main(String[] args)
    	{
    		// 下面程序创建了四个线程安全的集合对象
    		var c = Collections
    			.synchronizedCollection(new ArrayList());
    		var list = Collections.synchronizedList(new ArrayList());
    		var s = Collections.synchronizedSet(new HashSet());
    		var m = Collections.synchronizedMap(new HashMap());
    	}
    }
    

    四、设置不可变集合

    Collections提供如下三个方法来返回一个不可变集合:
    1、emptyXxx():返回一个空的不可变的集合对象,此处的集合可以是List、SortedSet、Set、Map、TreeMap等。
    2、singletonXxx():返回一个只包含指定对象(只有一个或一项元素)的、不可变的集合对象,此处的集合可以是List,也可以是Map。省略Xxx则是set
    3、unmodifiableXxx():返回指定集合对象的不可变视图,此处的集合可以是List、SortedSet、Set、Map、TreeMap等。
    上面三类方法的参数是原有的集合对象,返回值是该集合的"只读"版本。通过Collections提供的三类方法,可以生成只读的Collection或Map

    import java.util.*;
    public class unmodifiableTest
    {
    	public static void main(String[] args)
    	{
    		//创建一个空的不可变的List对象
    		var unmodifiableList=Collections.emptyList();
    		//创建一个只有一个元素、且不可变的Set对象
    		var unmodifiableSet=Collections.singleton("疯狂Java讲义");
    		//创建一个普通的Map对象
    		var scores=new HashMap();
    		scores.put("语文",90);
    		scores.put("数学",98);
    
    		//返回普通的Map对象对应的不可变版本
    		var unmodifiableMap=Collections.unmodifiableMap(scores);
    
    		//下面三条语句将引发Exception in thread "main" java.lang.UnsupportedOperationException
    		unmodifiableList.add("测试元素");
    		unmodifiableSet.add("测试元素");
    		unmodifiableMap.put("语文",92);
    	}
    }
    

    五、Java 9新增的不可变集合

    在以前如果需要创建一个包含6个元素的Set集合,程序需要先创建Set集合,然后调用6次add()方法向Set集合中添加元素。Java 9对此进行简化,程序直接调用Set、List、Map的of()方法即可创建包含N个元素的不可变集合,这样一行代码就可以创建包含N个元素的集合。
    不可变以为着不能向集合中添加元素,也不能从集合中删除元素。

    import java.util.*;
    public class Java9Collection
    {
    	public static void main(String[] args)
    	{
    		//创建包含4个元素的Set集合
    		var set=Set.of("Java","Kotlin","Go","Swift");
    		System.out.println(set);
    		//不可变集合,下面将导致运行时错误
    		//set.add("Ruby");//Exception in thread "main" java.lang.UnsupportedOperationException
    
    		//创建4个对象的List集合
    		var list=List.of(34,5,64,45);
    		System.out.println(list);
    		//不可变集合,下面将导致运行时错误
    		//list.remove(5);//Exception in thread "main" java.lang.UnsupportedOperationException
    
    		// 创建包含3组key-value对的Map集合
    		var map = Map.of("语文", 89, "数学", 82, "英语", 92);
    		System.out.println(map);
    		// 不可变集合,下面代码导致运行时错误
    //		map.remove("语文");
    		// 使用Map.entry()方法显式构建key-value对
    		var map2 = Map.ofEntries(Map.entry("语文", 89),
    			Map.entry("数学", 82),
    			Map.entry("英语", 92));
    		System.out.println(map2);
    	}
    }
    ---------- 运行Java捕获输出窗 ----------
    [Go, Swift, Java, Kotlin]
    [34, 5, 64, 45]
    {语文=89, 数学=82, 英语=92}
    {语文=89, 数学=82, 英语=92}
    
    输出完成 (耗时 0 秒) - 正常终止
    
  • 相关阅读:
    PYTHON 中的字符集
    字符集--发展史
    循序渐进Python3(十三) --7--  django之models
    循序渐进Python3(十三) --8--  django之admin
    循序渐进Python3(十三) --6--  cookie和session
    循序渐进Python3(十三) --5-- django请求处理流程
    循序渐进Python3(十三) --4-- django之csrf使用
    循序渐进Python3(十三) --3-- django之form表单(为自动生成的html标签添加样式)
    循序渐进Python3(十三) --2-- django之form表单(自动生成html标签和自定制提示信息)
    循序渐进Python3(十三) --1-- django之form表单
  • 原文地址:https://www.cnblogs.com/weststar/p/12588774.html
Copyright © 2020-2023  润新知