一般来说课本上的数据结构包括数组、单链表、堆栈、树、图。我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如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的使用如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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);
}
|
这段方法如果在主函数调用:
1
2
3
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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来确定最后一个元素的位置。如果在主函数这样调用这段方法:
1
2
3
|
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内容转化回一维数组:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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();
}
|
在主函数中这样调用方法:
1
2
3
|
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也不得进行排序操作
例如如下的一段方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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);
}
|
在主函数中,调用这个方法:
1
2
3
|
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改成三元组的错误操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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中的类。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。