欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解java中的Collections类

程序员文章站 2024-03-13 10:26:45
一般来说课本上的数据结构包括数组、单链表、堆栈、树、图。我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,string,do...

一般来说课本上的数据结构包括数组、单链表、堆栈、树、图。我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,string,double甚至一维数组、二维数组无法完全表达你要表达的东西,而定义一个类class有太过麻烦,这时候,你可以考虑一下用java中的collections类。使用collections类,必须在文件头声明import java.util.*;

一、动态、有序、可变大小的一维数组vector与arraylist 

collections类里面包括动态、有序、可变大小的一维数组vector与arraylist。 

vector与arraylist,两者唯一的差别是:vector自带线程互斥,多个线程对其读写会抛出异常,而arraylist则允许多个线程读写,其他部分是一模一样的,换句话说,如果是单线程在读写,使用vector与arraylist没有任何区别,但现在编程基本都用arraylist,使用vector有点非主流了。
 1、vector的使用如下:

 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);
 }

这段方法如果在主函数调用:

system.out.println("======vector数据结构的测试开始======");
 vectortest();
system.out.println("======vector数据结构的测试结束======");

运行结果如下: 
======vector数据结构的测试开始======
 单纯的add表示从结尾加入元素:[1.6, 2.06, 1]
 size()能求出vector的所含元素的个数:3
 remove(1)表示删去第1个元素,由于计数从0开始,也就是2.06这个元素:[1.6, 1]
 删去最后一个元素的vector为:[1.6]
 在第0个位置加入1.8888这个元素:[1.8888, 1.6]
 把第0个位置这个元素改为a:[a, 1.6]
 ======vector数据结构的测试结束======

2、arraylist

 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删除最后一个元素的方式与vector有所不同,主要是arraylist没有lastelement()这个方法来取出最后一个元素remove()掉,只能用arraylist.size() - 1来确定最后一个元素的位置。如果在主函数这样调用这段方法: 

 system.out.println("======arraylist数据结构的测试开始======");
 arraylisttest();
 system.out.println("======arraylist数据结构的测试结束======");

 则得到如下的运行结果: 
======arraylist数据结构的测试开始======
 单纯的add表示从结尾加入元素:[1.0, 4.0, 5.0, 2.3]
 size()能求出所含元素的个数:4
 remove(1)表示删去第1个元素,由于计数从0开始,也就是4这个元素:[1.0, 5.0, 2.3]
 删去最后一个元素的arraylist为:[1.0, 5.0]
 在第0个位置加入1.8888这个元素:[1.8888, 1.0, 5.0]
 把第0个位置这个元素改为a:[9.0, 1.0, 5.0]
 如果arraylist不是抽象类型,则支持排序[1.0, 5.0, 9.0]
 ======arraylist数据结构的测试结束====== 

从上面的两个例子,可以看到vector与arraylist比一个普通的数组,也就是课本上所教的一维数组int array[] = { 8, 7, 100, 88, 6, 4, 5, 33, 7 };强大很多,可以在任意位置插入元素,也可以不用遍历数组就能够用一个方法删除指定位置的元素,当然为你考试你还是要知道这个数组是怎么遍历的。其实,arraylist与普通的一维数组完全可以实现互转,而且利用arraylist还能够直接对array进行排序,而不用再对array写一个冒泡排序之类的,直接用collections.sort();就能够排序数组,然后再用collections.reverse();就能实现逆排序,当然还是那句,为你考试你还是要知道这个数组是怎么排序的。

比如如下的方法,实现了对一维数组int array[] = { 8, 7, 100, 88, 6, 4, 5, 33, 7 };的排序与逆排序,先把数组转化成arraylist再用collections.sort();与collections.reverse();排序,最后再把arraylist内容转化回一维数组: 

 public static void arraylistsort() {
 int array[] = { 8, 7, 100, 88, 6, 4, 5, 33, 7 };
 arraylist<integer> arraylist = new arraylist<integer>();
 for (int i = 0; i < array.length; i++)
 system.out.print(array[i] + ",");
 for (int i = 0; i < array.length; i++)
 arraylist.add(array[i]);
 collections.sort(arraylist);
 for (int i = 0; i < array.length; i++)
 array[i] = arraylist.get(i);
 system.out.print("排序后的数组:");
 for (int i = 0; i < array.length; i++)
 system.out.print(array[i] + ",");
 collections.reverse(arraylist);
 for (int i = 0; i < array.length; i++)
 array[i] = arraylist.get(i);
 system.out.print("逆排序后的数组:");
 for (int i = 0; i < array.length; i++)
 system.out.print(array[i] + ",");
 //排序之后把arraylist销毁
 arraylist = null;
 //这句是建议java马上回收垃圾,当然这句有没有都行,java在运行的过程中会自动清除垃圾的
 system.gc();

 }

  在主函数中这样调用方法: 

 system.out.println("======java数组排序开始======");
 arraylistsort();
 system.out.println("======java数组排序结束======");

就能够得到如下的运行结果: 
======java数组排序开始======
 8,7,100,88,6,4,5,33,7,排序后的数组:4,5,6,7,7,8,33,88,100,逆排序后的数组:100,88,33,8,7,7,6,5,4, 
======java数组排序结束====== 
另外,之前说的《java中list的使用方法简单介绍》()也是同样的道理 

二、集合hashset 
另外,还有集合hashset,hashset与数学上的集合概念一模一样。由一个或多个元素所构成的叫做集合。hashset具有:
1.确定性,集合中的元素必须是确定的,这个是废话,必须确定,难道我还可以在里面放一个不确定的东西进去吗? 
2.互异性,集合中的元素互不相同。例如:集合a={1,a},则a不能等于1,也就是如果你把两个1放进hashset会自动变为一个1 
3.无序性,集合中的元素没有先后之分。因此hashset也不得进行排序操作 
例如如下的一段方法: 

 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);
 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);
 }

在主函数中,调用这个方法:

 system.out.println("======hashset数据结构的测试开始======");
 hashsettest();
 system.out.println("======hashset数据结构的测试结束======"); 

结果如下: 
======hashset数据结构的测试开始======
 单纯的add表示从结尾加入元素:[1, 5, 2.3]
 size()能求出所含元素的个数:3
 remove(1)表示删去'1'这个元素:[5, 2.3]
 如果没有'asd'这个元素则remove什么都不做:[5, 2.3]
 加入1.8888这个元素:[5, 1.8888, 2.3]
 ======hashset数据结构的测试结束======
 hashset有add()方法与remove()方法,add()所加的元素没有顺序,每次用system.out.println()打印的结果可能顺序不一样,也不能向上面vector与arraylist一样,只要所存的元素不是object,就能使用collections.sort(arraylist);来排序 

三、二元组hashmap
这里的使用方法和上面的数据基本相同,也很简单,就是put方法来对象进去map,而get能够取走map中的对象,但是试图把二元组hashmap用成三元组是错误的,如果一个对象中含有元素过多,那你应该考虑用类。而不是还在迷恋java中介乎于普通变量与class类之间的collections类。
比如如下方法就展示了试图把hashmap改成三元组的错误操作: 

 public static void maptest(){
 system.out.println("======map错误的使用开始======");
 hashmap<string,string> map=new hashmap<string, string>();
 hashmap<string,hashmap<string, string>> bigmap=new hashmap<string, hashmap<string, string>>();
 map.put("key1","1");
 map.put("key2","2"); 
 bigmap.put("test1",map);
 map.clear();
 map.put("key1","3");
 map.put("key2","4"); 
 bigmap.put("test2",map);
 system.out.println(bigmap);
 system.out.println(bigmap.get("test1").get("key1"));
 system.out.println(bigmap.get("test1").get("key2"));
 system.out.println(bigmap.get("test2").get("key1"));
 system.out.println(bigmap.get("test2").get("key2"));
 system.out.println("======map错误的使用结束======");
 system.out.println("======map正确的使用开始======");
 map.clear();
 bigmap=null;
 map.put("key1","1");
 map.put("key2","2");
 map.put("key3","3");
 system.out.println(map);
 system.out.println("======map正确的使用结束======");
 }

在主函数调用这段代码,得到下面的运行结果: 
======map数据结构的测试开始======
 ======map错误的使用开始======
 {test1={key2=4, key1=3}, test2={key2=4, key1=3}}
 3
 4
 3
 4
 ======map错误的使用结束======
 ======map正确的使用开始======
 {key3=3, key2=2, key1=1}
 ======map正确的使用结束======
 ======map数据结构的测试结束======
这段程序本来用意是很明显,试图构造出一个{test1,key1,1},{test1,key2,2},{test2,key3,3},{test2,key4,4} 
然而,每个bigmap中还是存得都是那个map,你一旦把map清空,原来test1中的那个map也同样被清空, 有人试图创造多个map1,map2,...那你还不如用一个简单的类,看起来更加明确,而且类中以后还能写方法,被继承 

四、备注
 在创造一个新的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>();没人敢说你不懂java中的类。

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。