Java进阶(三十九)Java集合类的排序,查找,替换操作
Java进阶(三十九)Java集合类的排序,查找,替换操作
前言
在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组。获取到ArrayList对象后,我们可以根据Collection中的方法进行排序,查找,替换操作。而不用在东奔西走的利用什么各种排序算法、正则来实现了。在进行数组排序时,有时反而会因为参数问题而大费周折。例如,自己在利用快排进行数组排序时,当将参数(int [] a, 使用1来代替
Collections.frequency(nums,-5); //判断-5在List集合中出现的次数
Collections.binarySearch(nums,3); //使用两分法查询,只有对先List排好序才能用二分法查找
Collections工具类提供了大量针对Collection/Map的操作,总体可分为四类,都为静态(static)方法:
1. 排序操作(主要针对List接口相关)
reverse(List list):反转指定List集合中元素的顺序
shuffle(List list):对List中的元素进行随机排序(洗牌)
sort(List list):对List里的元素根据自然升序排序
sort(List list, Comparator c):自定义比较器进行排序
swap(List list, int i, int j):将指定List集合中i处元素和j出元素进行交换
rotate(List list, int distance):将所有元素向右移位指定长度,如果distance等于size那么结果不变
public void testSort() { System.out.println("原始顺序:" + list); Collections.reverse(list); System.out.println("reverse后顺序:" + list); Collections.shuffle(list); System.out.println("shuffle后顺序:" + list); Collections.swap(list, 1, 3); System.out.println("swap后顺序:" + list); Collections.sort(list); System.out.println("sort后顺序:" + list); Collections.rotate(list, 1); System.out.println("rotate后顺序:" + list); }
2.查找和替换(主要针对Collection接口相关)
binarySearch(List list, Object key):使用二分搜索法,以获得指定对象在List中的索引,前提是集合已经排序
max(Collection coll):返回最大元素
max(Collection coll, Comparator comp):根据自定义比较器,返回最大元素
min(Collection coll):返回最小元素
min(Collection coll, Comparator comp):根据自定义比较器,返回最小元素
fill(List list, Object obj):使用指定对象填充
frequency(Collection Object o):返回指定集合中指定对象出现的次数
replaceAll(List list, Object old, Object new):替换
public void testSearch() { System.out.println("给定的list:" + list); System.out.println("max:" + Collections.max(list)); System.out.println("min:" + Collections.min(list)); System.out.println("frequency:" + Collections.frequency(list, "a李四")); Collections.replaceAll(list, "a李四", "aa李四"); System.out.println("replaceAll之后:" + list); // 如果binarySearch的对象没有排序的话,搜索结果是不确定的 System.out.println("binarySearch在sort之前:" + Collections.binarySearch(list, "c赵五")); Collections.sort(list); // sort之后,结果出来了 System.out.println("binarySearch在sort之后:" + Collections.binarySearch(list, "c赵五")); Collections.fill(list, "A"); System.out.println("fill:" + list); }
3.同步控制
Collections工具类中提供了多个synchronizedXxx方法,该方法返回指定集合对象对应的同步对象,从而解决多线程并发访问集合时线程的安全问题。HashSet、ArrayList、HashMap都是线程不安全的,如果需要考虑同步,则使用这些方法。这些方法主要有:synchronizedSet、synchronizedSortedSet、synchronizedList、synchronizedMap、synchronizedSortedMap。
特别需要指出的是,在使用迭代方法遍历集合时需要手工同步返回的集合。
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized (m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
4.设置不可变集合
Collections有三类方法可返回一个不可变集合:
emptyXxx():返回一个空的不可变的集合对象
singletonXxx():返回一个只包含指定对象的,不可变的集合对象。
unmodifiableXxx():返回指定集合对象的不可变视图
public void testUnmodifiable() { System.out.println("给定的list:" + list); List<String> unmodList = Collections.unmodifiableList(list); unmodList.add("再加个试试!"); // 抛出:java.lang.UnsupportedOperationException // 这一行不会执行了 System.out.println("新的unmodList:" + unmodList); }
5.其它
disjoint(Collection<?> c1, Collection<?> c2) - 如果两个指定 collection 中没有相同的元素,则返回 true。
addAll(Collection<? super T> c, T... a) - 一种方便的方式,将所有指定元素添加到指定 collection 中。
示范:
Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
Comparator<T> reverseOrder(Comparator<T> cmp) - 返回一个比较器,它强行反转指定比较器的顺序。如果指定比较器为 null,则此方法等同于 reverseOrder()(换句话说,它返回一个比较器,该比较器将强行反转实现 Comparable 接口那些对象 collection 上的自然顺序)。
public void testOther() { List<String> list1 = new ArrayList<String>(); List<String> list2 = new ArrayList<String>(); // addAll增加变长参数 Collections.addAll(list1, "大家好", "你好","我也好"); Collections.addAll(list2, "大家好", "a李四","我也好"); // disjoint检查两个Collection是否的交集 boolean b1 = Collections.disjoint(list, list1); boolean b2 = Collections.disjoint(list, list2); System.out.println(b1 + "\t" + b2); // 利用reverseOrder倒序 Collections.sort(list1, Collections.reverseOrder()); System.out.println(list1); } 6. 完整代码 import java.util.*; import org.junit.Before; import org.junit.Test; public class CollectionsTest { private List<String> list = new ArrayList<String>(); @Before public void init() { // 准备测试数据 list.add("b张三"); list.add("d孙六"); list.add("a李四"); list.add("e钱七"); list.add("c赵五"); } @Test public void testUnmodifiable() { System.out.println("给定的list:" + list); List<String> unmodList = Collections.unmodifiableList(list); unmodList.add("再加个试试!"); // 抛出:java.lang.UnsupportedOperationException // 这一行不会执行了 System.out.println("新的unmodList:" + unmodList); } @Test public void testSort() { System.out.println("原始顺序:" + list); Collections.reverse(list); System.out.println("reverse后顺序:" + list); Collections.shuffle(list); System.out.println("shuffle后顺序:" + list); Collections.swap(list, 1, 3); System.out.println("swap后顺序:" + list); Collections.sort(list); System.out.println("sort后顺序:" + list); Collections.rotate(list, 1); System.out.println("rotate后顺序:" + list); } @Test public void testSearch() { System.out.println("给定的list:" + list); System.out.println("max:" + Collections.max(list)); System.out.println("min:" + Collections.min(list)); System.out.println("frequency:" + Collections.frequency(list, "a李四")); Collections.replaceAll(list, "a李四", "aa李四"); System.out.println("replaceAll之后:" + list); // 如果binarySearch的对象没有排序的话,搜索结果是不确定的 System.out.println("binarySearch在sort之前:" + Collections.binarySearch(list, "c赵五")); Collections.sort(list); // sort之后,结果出来了 System.out.println("binarySearch在sort之后:" + Collections.binarySearch(list, "c赵五")); Collections.fill(list, "A"); System.out.println("fill:" + list); } @Test public void testOther() { List<String> list1 = new ArrayList<String>(); List<String> list2 = new ArrayList<String>(); // addAll增加变长参数 Collections.addAll(list1, "大家好", "你好","我也好"); Collections.addAll(list2, "大家好", "a李四","我也好"); // disjoint检查两个Collection是否的交集 boolean b1 = Collections.disjoint(list, list1); boolean b2 = Collections.disjoint(list, list2); System.out.println(b1 + "\t" + b2); // 利用reverseOrder倒序 Collections.sort(list1, Collections.reverseOrder()); System.out.println(list1); } }
附 Java集合框架图
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。
我们可以看到Collection是List、Set、Queue接口的父接口,故该接口中定义的方法可用于操作List、Set、Queue集合。
发现一个特点,上述所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说如果是先Iterator接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap;而那些元素有序的集合,实现的一般都是LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,比如ArrayList。
还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
美文美图
Java进阶(三十九)Java集合类的排序,查找,替换操作的更多相关文章
- Java进阶(三十五)java int与integer的区别
Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...
- Java进阶(三十四)Integer与int的种种比较你知道多少?
Java进阶(三十四)Integer与int的种种比较你知道多少? 前言 如果面试官问Integer与int的区别:估计大多数人只会说到两点:Ingeter是int的包装类,注意是一个类:int的初值 ...
- Java进阶(三十八)快速排序
Java进阶(三十八)快速排序 前言 有没有既不浪费空间又可以快一点的排序算法呢?那就是"快速排序"啦!光听这个名字是不是就觉得很高端呢. 假设我们现在对"6 1 2 7 ...
- Java进阶(三十六)深入理解Java的接口和抽象类
Java进阶(三十六)深入理解Java的接口和抽象类 前言 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太 ...
- Java进阶(三十二) HttpClient使用详解
Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...
- “全栈2019”Java第三十九章:构造函数、构造方法、构造器
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Java进阶(二十五)Java连接mysql数据库(底层实现)
Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...
- Java进阶专题(十九) 消息中间件架构体系(1)-- ActiveMQ研究
前言 MQ全称为Message Queue,即消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开 发中应用非常广泛.开发中消息队列通常有如下应用场景:1.任务异步处理.将不需要同步处理的 ...
- Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式
Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...
随机推荐
- [LSGDOJ 1299]搭配买卖
题目描述 joe觉得云朵很美,决定去山上的商店买一些云朵.商店里有n多云,云朵被编号为1,2,……,n,并且每朵云都有一个价值.但商店老板跟他说,一些云朵要搭配来买才好,所以买一朵云则与这多云有搭配的 ...
- ●BZOJ 2839 集合计数
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2839 题解: 容斥原理 真的是神题!!! 定义 f[k] 表示交集大小至少为 k时的方案数怎 ...
- [UOJ UNR#2 黎明前的巧克力]
来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 很奇妙的一道题 首先不难发现一个暴力做法,就是f[i]表示异或和为i的答案数,每次FWT上一个F数组,其中F[0]=1,F[ai]=2 ...
- 对中断的理解handle_level_irq【原创】
如下为本人原创,在解决问题的过程中的一点心得,如果有描述不准确的地方还请各位指出,非常感谢 Linux内核版本:linux-4.9.18 曾有一次调试触摸屏的时候遇到如下的问题 /startup/mo ...
- Spring使用@Scheduled定时调度
一.spring配置文件中增加对这个注解的支持: 配置文件如下: <?xml version="1.0" encoding="UTF-8"?> &l ...
- 如何导入python中的模块
作为一名新手Python程序员,你首先需要学习的内容之一就是如何导入模块或包.但是我注意到,那些许多年来不时使用Python的人并不是都知道Python的导入机制其实非常灵活.在本文中,我们将探讨以下 ...
- Tensorflow从入门到精通之——Tensorflow基本操作
前边的章节介绍了什么是Tensorflow,本节将带大家真正走进Tensorflow的世界,学习Tensorflow一些基本的操作及使用方法.同时也欢迎大家关注我们的网站和系列教程:http://ww ...
- 解决ansible首次连接host服务器需验证问题
问题描述: [root@iZm5e79rtwsq2hm57teyk5Z ansible]# ansible aofeng -f 5 -m ping 47.93.18.191 | FAILED! =&g ...
- TeamForge使用指南
1.什么是TeamForge 可以把TeamForge简单的理解为另外一种github 2.TeamForge的地址 与Project有关,一般会有明确的Link 3.TeamForge登录 用户名和 ...
- Spring常用接口和类
一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...