Java中的Collections类
转载:https://blog.csdn.net/yangxingpa/article/details/80515963
从【Java】Java中的Collections类——Java中升级版的数据结构中学习整理而来。
一、 动态、有序、可变大小的一维数组Vector与ArrayList
Collections类里面包括动态、有序、可变大小的一维数组Vector与ArrayList。
Vector与ArrayList,两者唯一的差别是:vector自带线程互斥,多个线程对其读写会抛出异常,而arraylist则允许多个线程读写,其他部分是一模一样的,换句话说,如果是单线程在读写,使用Vector与ArrayList没有任何区别,但现在编程基本都用ArrayList,使用Vector有点非主流了。
1、Vector的使用如下:
常用方法总结:
Vector<Object> vector = new Vector<Object>(); vector.add(1.6);:单纯的add表示从结尾加入元素 vector.size():size()能求出vector的所含元素的个数 vector.remove(1);:remove(1)表示删去第1个元素,注意计数从0开始 vector.remove(vector.lastElement());:删去最后一个元素 vector.add(0, 1.8888); :在第0个位置 加入 1.8888这个元素 vector.set(0, "a");:把第0个位置这个元素 改为 a
public static void Vectortest() { // Vector<Double>表示这个vector只能存放double // Vector<String>表示这个vector只能存String // 虽然Vector<Object> vector=new Vector<Object>();等价于Vector vector=new // Vector();但是,eclipse中这样写会警告,表示你这个Vector不规范 Vector<Object> vector = new Vector<Object>(); vector.add(1.6); vector.add(2.06); vector.add(1); System.out.println("单纯的add表示从结尾加入元素:" + vector); System.out.println("size()能求出vector的所含元素的个数:" + vector.size()); vector.remove(1); System.out.println("remove(1)表示删去第1个元素,由于计数从0开始,也就是2.06这个元素:" + vector); vector.remove(vector.lastElement()); System.out.println("删去最后一个元素的vector为:" + vector); vector.add(0, 1.8888); System.out.println("在第0个位置加入1.8888这个元素:" + vector); vector.set(0, "a"); System.out.println("把第0个位置这个元素改为a:" + vector); }
2、ArrayList使用方法
常用方法总结: ArrayList<Double> arraylist = new ArrayList<Double>();
1. arraylist.add(1.0);:单纯的add表示从结尾加入元素 2. arraylist.size();:size()能求出所含元素的个数 3. arraylist.remove(1);:remove(1)表示删去第1个元素,注意计数从0开始 4. arraylist.remove(arraylist.size() - 1);:删去最后一个元素 5. arraylist.add(0, 1.8888); :在第0个位置 加入 1.8888这个元素 6. arraylist.set(0, 9.0);:把第0个位置这个元素 改为 9.0 7. Collections.sort(arraylist); :如果arraylist不是抽象类型,则支持排序 8. arraylist.get(i);:得到第i个位置的元素值,注意从0开始计数。
public static void ArrayListtest() { ArrayList<Double> arraylist = new ArrayList<Double>(); arraylist.add(1.0); arraylist.add(4.0); arraylist.add(5.0); arraylist.add(2.3); System.out.println("单纯的add表示从结尾加入元素:" + arraylist); System.out.println("size()能求出所含元素的个数:" + arraylist.size()); arraylist.remove(1); System.out.println("remove(1)表示删去第1个元素,由于计数从0开始,也就是4这个元素:" + arraylist); arraylist.remove(arraylist.size() - 1); System.out.println("删去最后一个元素的arraylist为:" + arraylist); arraylist.add(0, 1.8888); System.out.println("在第0个位置加入1.8888这个元素:" + arraylist); arraylist.set(0, 9.0); System.out.println("把第0个位置这个元素改为a:" + arraylist); Collections.sort(arraylist); System.out.println("如果arraylist不是抽象类型,则支持排序" + arraylist); }
ArrayList与普通的一维数组完全可以实现互转,而且利用ArrayList还能够直接对array进行排序,而不用再对array写一个冒泡排序之类的,直接用Collections.sort();就能够排序数组,然后再用Collections.reverse();就能实现逆排序:
Collections.sort(arraylist);//排序 Collections.reverse(arraylist);//逆序
扩展:List
:集合对象
Java中的List就是一种集合对象,将所有的对象集中到一起存储。List里面可以放任意的java对象,也可以直接放值。
使用方法很简单,类似于数组。
使用List之前必须在程序头引入java.util.*
涉及到的方法有:
List a=new ArrayList(); a.add(1);//在LIST a中添加1 System.out.println(a); a.add(2); System.out.println(a); a.remove(0);//在LIST a中移除第0个元素,也就是1 System.out.println(a); //程序的运行结果如下: //[1] //[1, 2] //[2]
二、集合:HashSet
HashSet与数学上的集合概念一模一样。由一个或多个元素所构成的叫做集合。
HashSet具有:
- 确定性,集合中的元素必须是确定的。
- 互异性,集合中的元素互不相同。例如:集合A={1,a},则a不能等于1,也就是如果你把两个1放进HashSet会自动变为一个1。
- 无序性,集合中的元素没有先后之分。因此HashSet也不得进行排序操作。
常用方法总结:
HashSet<Object> hashset = new HashSet<Object>(); 1. hashset.add(1);:错误理解:单纯的add表示从结尾加入元素;正确理解:在hashset中插入元素“1”,位置不确定! 2. hashset.size():size()能求出所含元素的个数 3. hashset.remove(1);:remove(1)表示删去“1”这个元素 4. hashset.remove("asd");:如果没有’asd’这个元素则remove什么都不做 5. HashSet有add()方法与remove()方法,add()所加的元素没有顺序
public static void HashSettest() { HashSet<Object> hashset = new HashSet<Object>(); hashset.add(1); hashset.add(1); hashset.add(5); hashset.add(2.3); System.out.println("add表示在hashset中插入元素,但位置不确定:" + hashset); System.out.println("size()能求出所含元素的个数:" + hashset.size()); hashset.remove(1); System.out.println("remove(1)表示删去'1'这个元素:" + hashset); hashset.remove("asd"); System.out.println("如果没有'asd'这个元素则remove什么都不做:" + hashset); hashset.add(1.8888); System.out.println("加入1.8888这个元素:" + hashset); }
三、二元组:HashMap
这里的使用方法和上面的数据基本相同,也很简单,就是put方法来对象进去map,而get能够取走map中的对象,但是试图把二元组HashMap用成三元组是错误的,如果一个对象中含有元素过多,那你应该考虑用类。而不是还在迷恋Java中介乎于普通变量与Class类之间的Collections类。
关于其的更多学习:参考Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例
- HashMap就是一个散列表,它是通过“拉链法”解决哈希冲突的。
- 影响HashMap性能的有两个参数:初始容量(initialCapacity) 和加载因子(loadFactor)。容量 是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
- HashMap的主要对外接口
clear()
:clear() 的作用是清空HashMap。它是通过将所有的元素设为null来实现的。containsKey()
:containsKey() 的作用是判断HashMap是否包含key。containsValue()
:containsValue() 的作用是判断HashMap是否包含“值为value”的元素。entrySet()、values()、keySet()
:它们3个的原理类似,这里以entrySet()为例来说明。entrySet()的作用是返回“HashMap中所有Entry的集合”,它是一个集合。get()
:get() 的作用是获取key对应的value。put()
:put() 的作用是对外提供接口,让HashMap对象可以通过put()将“key-value”添加到HashMap中。若要添加到HashMap中的键值对对应的key已经存在HashMap中,则找到该键值对;然后新的value取代旧的value,并退出!若要添加到HashMap中的键值对对应的key不在HashMap中,则将其添加到该哈希值对应的链表中,并调用addEntry()。addEntry() 的作用是新增Entry。将“key-value”插入指定位置,bucketIndex是位置索引。putAll()
:putAll() 的作用是将”m”的全部元素都添加到HashMap中。remove()
:remove() 的作用是删除“键为key”元素。
总结: void clear() Object clone() boolean containsKey(Object key) boolean containsValue(Object value) Set<Entry<K, V>> entrySet() V get(Object key) boolean isEmpty() Set<K> keySet() V put(K key, V value) void putAll(Map<? extends K, ? extends V> map) V remove(Object key) int size() Collection<V> values()
四、使用技巧
在创造一个新的Vector,Arraylist好,HashSet也好,HashMap也好,完全可以写成:
Collection<String> a= new ArrayList<String>(); List<String> a= new Vector<String>();
之类
因为继承于Collection接口的有ArrayList、Vector、Linkedlist、HashSet、TreeSet,继承于MAP接口的有HashMap、Hashtable,这是Java中类的继承、多态、封装之类的问题。当然可以写更加简洁的写法:ArrayList<Integer> arraylist = new ArrayList<Integer>();
五、Collections中sort方法Comparator的重写
sort
方法:其中的一个参数是接口!!! 定义好排序规则,设置好返回值,马上变成排序利器!
注意现实:比较器Comparator是一个接口!
设定比较规则,即自定义比较器Comparator:
//自己定义的类结构 class Student { public int s_no; public String s_name; public int s_class; } //待排序的对象实例 ArrayList<Student> studentArr = new ArrayList<Student>(); //重新写比较器 //Comparator接口,两个对象要使用compareTo方法比较大小,就必须实现Comparator接口的compare方法; //比如String就实现了这个方法,所以可以直接使用compareTo进行比较。 //sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序。 Collections.sort(studentArr, new Comparator<Object>() { @Override public int compare(Object o1, Object o2){ //你首先设置你要比较的东西 //具体是把参数中的Object强制转换成你要比较的东西,这里是两个Student类 //这里的s1,s2与上面的s1,s2一点关系都没有,只是抽象的前者与后者的关系 Student s1 = (Student) o1; Student s2 = (Student) o2; //如果前者的学号大于后者的学号,就是前者大于后者,返回1系统就会识别是前者大于后者 if (s1.s_no > s2.s_no) { return 1; } //小于同理 if (s1.s_no < s2.s_no) { return -1; } //如果返回0则认为前者与后者相等 return 0; } });
值得一看的例子:
【Java】Collections中sort方法Comparator的重写
import java.util.*; //以下是学生类Student定义,有点类似C语言的结构体啊!^_^ class Student { public int s_no; public String s_name; public int s_class; } public class compareTest { public static void main(String[] args) { //存放学生类的动态数组的初始化 ArrayList<Student> studentArr = new ArrayList<Student>(); Student s1 = new Student(); s1.s_no = 3; s1.s_name = "a"; s1.s_class = 102; studentArr.add(s1); Student s2 = new Student(); s2.s_no = 2; s2.s_name = "b"; s2.s_class = 101; studentArr.add(s2); Student s3 = new Student(); s3.s_no = 1; s3.s_name = "c"; s3.s_class = 103; studentArr.add(s3); //初始化之后先打印以下这个动态数组 System.out.println("排序前:"); for (int i = 0; i < studentArr.size(); i++) { System.out .println("我是" + studentArr.get(i).s_class + "班的" + studentArr.get(i).s_name + "学号是" + studentArr.get(i).s_no); } //对于Comparator接口的重写 //这个接口就一个抽象函数,给出的参数与返回值都是定死的。 Collections.sort(studentArr, new Comparator<Object>() { public int compare(Object o1, Object o2) { //你首先设置你要比较的东西 //具体是把参数中的Object强制转换成你要比较的东西,这里是两个Student类 //这里的s1,s2与上面的s1,s2一点关系都没有,只是抽象的前者与后者的关系 Student s1 = (Student) o1; Student s2 = (Student) o2; //如果前者的学号大于后者的学号,就是前者大于后者,返回1系统就会识别是前者大于后者 if (s1.s_no > s2.s_no) { return 1; } //小于同理 if (s1.s_no < s2.s_no) { return -1; } //如果返回0则认为前者与后者相等 return 0; } }); //比较完毕再输出以学号排序之后的结果 System.out.println("按学号升序排序后:"); for (int i = 0; i < studentArr.size(); i++) { System.out .println("我是" + studentArr.get(i).s_class + "班的" + studentArr.get(i).s_name + "学号是" + studentArr.get(i).s_no); } //以下是以班级排序的过程 Collections.sort(studentArr, new Comparator<Object>() { public int compare(Object o1, Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; if (s1.s_class > s2.s_class) { return 1; } if (s1.s_class < s2.s_class) { return -1; } return 0; } }); System.out.println("按班级升序排序后:"); for (int i = 0; i < studentArr.size(); i++) { System.out .println("我是" + studentArr.get(i).s_class + "班的" + studentArr.get(i).s_name + "学号是" + studentArr.get(i).s_no); } } }