7.8 操作集合的工具类:Collections
Posted weststar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 秒) - 正常终止
以上是关于7.8 操作集合的工具类:Collections的主要内容,如果未能解决你的问题,请参考以下文章