JAVA常用集合框架
Java中集合类定义主要是在java.util.*包下面,常用的集合在系统中定义了三大接口,这三类的区别是:
java.util.Set接口及其子类,set提供的是一个无序集;
java.util.List接口及其子类,List提供的是一个有序集;
java.util.Map接口及其子类,Map提供了一个映射关系的集合数据结构;
每种集合都可以理解为用来在内存中存放一组对象的某种“容器”。
java.util.List接口的实现类的特点和用法:
List接口提供了多个实现的子类,常用的实现类是java.util.Vector和java.util.ArrayList,现在以java.util.ArrayList为例来说明List的特点及用法,具体代码示例如下:
public class ArrayListTest {
//主函数
public static void main(String args[]){
//创建队列对象
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
//向队列中添加元素
for (int i=0;i<10;i++){
String str = "学生"+i;
list.add(str);
}
//遍历1
for (int i=0;i<list.size();i++){
//根据下标取出队列的元素
String str = list.get(i);
System.out.print(str+"\t");
}
System.out.println();
//遍历2
//得到队列的迭代器对象
java.util.Iterator<String> itr = list.iterator();
//判断是否有数据可以迭代
while(itr.hasNext()){
//取出一个元素
String str = itr.next();
System.out.print(str+"\t");
}
System.out.println();
//遍历3
for (String str:list){
System.out.print(str+"\t");
}
}
}
运行结果:
学生0学生1学生2学生3学生4学生5学生6学生7学生8学生9
学生0学生1学生2学生3学生4学生5学生6学生7学生8学生9
学生0学生1学生2学生3学生4学生5学生6学生7学生8学生9
以上程序是先创建一个队列对象list,然后以有序的元素添加到该队列中,接下来是通过三种不同的方式遍历该队列的,第一种是通过下标值来遍历队列的,打印出来的队列也是有序的,但是仅凭这一种方式不能说明队列是有序的,所以再通过第二种遍历方式,打印出该队列,第二种遍历是先得到队列的迭代器对象,在判断是否有数据可以迭代,最后取出队列的元素。通过第二种遍历方式就可以说明队列是有序的,这两种遍历方式也都说明了队列是线性的。第三种遍历方式是在java中特有的遍历方式。
下面再把上面的代码做稍微的修改,如下所示:
public class ArrayListTest {
//主函数
public static void main(String args[]){
//创建队列对象
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
//向队列中添加元素
for (int i=0;i<15;i++){
String str = "学生"+i;
list.add(str);
}
list.add("新同学");
list.add("新同学");
list.add("新来的");
//遍历1
for (int i=0;i<list.size();i++){
//根据下标取出队列的元素
String str = list.get(i);
System.out.print(str+"\t");
}
System.out.println();
//遍历2
//得到队列的迭代器对象
java.util.Iterator<String> itr = list.iterator();
//判断是否有数据可以迭代
while(itr.hasNext()){
//取出一个元素
String str = itr.next();
System.out.print(str+"\t");
}
System.out.println();
//遍历3
for (String str:list){
System.out.print(str+"\t");
}
}
}
运行结果:
学生0学生1学生2学生3学生4学生5学生6学生7学生8学生9学生10学生11学生12学生13学生14新同学新同学新来的
学生0学生1学生2学生3学生4学生5学生6学生7学生8学生9学生10学生11学生12学生13学生14新同学新同学新来的
学生0学生1学生2学生3学生4学生5学生6学生7学生8学生9学生10学生11学生12学生13学生14新同学新同学新来的
以上程序添加是在队列中添加了新的元素,并且有添加相同的元素,从运行结果可知,队列是长度可变的,可以有相同重复的元素。
根据以上两段代码的运行结果可知,队列的特点是线性的,有序的,长度可变的,有下标值的,元素可重复的。
Java.util.Set接口的实现类的特点及用法:
Set是一个接口定义,所以只能使用它的实现子类,Set接口常用的子类有java.util.HashSet、java.util.TreeSet;这里以java.util.HashSet为例说明它的特点及用法,请看下面代码示例:
public class HashSetTest {
//主函数
public static void main(String args[]){
//创建集合对象
java.util.HashSet<String> set = new java.util.HashSet<String>();
//向集合中添加元素
for (int i=0;i<10;i++){
String str = "学生"+i;
set.add(str);
}
//遍历1
//得到迭代器的对象
java.util.Iterator<String> iter = set.iterator();
while(iter.hasNext()){
String str = iter.next();
System.out.print(str+"\t");
}
System.out.println();
//遍历2
for (String str:set){
System.out.print(str+"\t");
}
}
}
运行结果:
学生0学生9学生7学生8学生5学生6学生3学生4学生1学生2
学生0学生9学生7学生8学生5学生6学生3学生4学生1学生2
以上程序是将有序的元素放入的集合中,通过第一种遍历方式打印出来的元素是无序的,说明集合的特点是无序的。下面再在上面的代码的基础上添加新的元素,代码如下:
public class HashSetTest {
//主函数
public static void main(String args[]){
//创建集合对象
java.util.HashSet<String> set = new java.util.HashSet<String>();
//向集合中添加元素
for (int i=0;i<10;i++){
String str = "学生"+i;
set.add(str);
}
set.add("新来的");
set.add("新同学");
//遍历1
//得到迭代器的对象
java.util.Iterator<String> iter = set.iterator();
while(iter.hasNext()){
String str = iter.next();
System.out.print(str+"\t");
}
System.out.println();
//遍历2
for (String str:set){
System.out.print(str+"\t");
}
}
}
运行结果:
学生0新同学学生9学生7学生8新来的学生5学生6学生3学生4学生1学生2
学生0新同学学生9学生7学生8新来的学生5学生6学生3学生4学生1学生2
从运行结果中可知集合和队列一样,长度也是可以变的。
下面在修改以上代码,向集合中添加相同的元素,如下所示:
public class HashSetTest {
//主函数
public static void main(String args[]){
//创建集合对象
java.util.HashSet<String> set = new java.util.HashSet<String>();
//向集合中添加元素
for (int i=0;i<10;i++){
String str = "学生"+i;
set.add(str);
}
set.add("新来的");
set.add("新同学");
set.add("新同学");
//遍历1
//得到迭代器的对象
java.util.Iterator<String> iter = set.iterator();
while(iter.hasNext()){
String str = iter.next();
System.out.print(str+"\t");
}
System.out.println();
//遍历2
for (String str:set){
System.out.print(str+"\t");
}
}
}
运行结果:
学生0新同学学生9学生7学生8新来的学生5学生6学生3学生4学生1学生2
学生0新同学学生9学生7学生8新来的学生5学生6学生3学生4学生1学生2
运行结果是和上面一样的,说明重复的元素只能够添加一个,到底添加了哪一个呢?可以通过打印来看添加的是哪一个,代码如下:
public class HashSetTest {
//主函数
public static void main(String args[]){
//创建集合对象
java.util.HashSet<String> set = new java.util.HashSet<String>();
//向集合中添加元素
for (int i=0;i<10;i++){
String str = "学生"+i;
set.add(str);
}
set.add("新来的");
boolean st1 = set.add("新同学");
boolean st2 = set.add("新同学");
System.out.println(st1+"<>"+st2);
//遍历1
//得到迭代器的对象
java.util.Iterator<String> iter = set.iterator();
while(iter.hasNext()){
String str = iter.next();
System.out.print(str+"\t");
}
System.out.println();
//遍历2
for (String str:set){
System.out.print(str+"\t");
}
}
}
运行结果:
true<>false
学生0新同学学生9学生7学生8新来的学生5学生6学生3学生4学生1学生2
学生0新同学学生9学生7学生8新来的学生5学生6学生3学生4学生1学生2
从运行结果来看,添加的是第一个相同的元素。从以上的代码运行的结果中可知道,集合的特点是长度可变的,无序的,元素是不重复的。
Java.util.Map接口的特点及用法:
Java提供了专门的集合类用来存放映射对象的,即Java.util.Map接口,Map是一个接口,有多种具体的实现类,常用的有HashMap和Hashtable类实现。Map中存入的对象是一对一对的,即每个对象和它的一个键关联在一起。从API文档中可知,Map中存放的是两种对象,一种称为key(键),一种称为value(值),他们在Map中是一一对应关系。Map中的键是不能重复的,但值是可以重复的。下面以java.util.HashMap为例说明它的特点及用法,请看下面的示例代码:
public class HashMapTest {
//主函数
public static void main(String args[]){
//创建一个映射对象
java.util.HashMap<Integer,String> map = new java.util.HashMap<Integer,String>();
//装入键值对
for (int i=0;i<10;i++){
int key = i*1000;
String value = "学生"+i;
map.put(key, value);
}
//遍历
//得到K的set集合
java.util.Set<Integer> set = map.keySet();
//遍历K的集合,得到K的迭代器对象
java.util.Iterator<Integer> iter = set.iterator();
while(iter.hasNext()){
int num = iter.next();
String str = map.get(num);
System.out.println(num+"\t"+str);
}
}
}
运行结果:
0学生0
1000学生1
2000学生2
3000学生3
4000学生4
5000学生5
6000学生6
7000学生7
8000学生8
9000学生9
上面的程序是向映射中添加入有序的元素,打印出的也是有序的元素,从运行的结果看,认为映射是有序的,但是稍微改一下程序,元素顺序结果就不一样了,代码如下:
public class HashMapTest {
//主函数
public static void main(String args[]){
//创建一个映射对象
java.util.HashMap<Integer,String> map = new java.util.HashMap<Integer,String>();
//装入键值对
for (int i=0;i<15;i++){
int key = i*1000;
String value = "学生"+i;
map.put(key, value);
}
//遍历
//得到K的set集合
java.util.Set<Integer> set = map.keySet();
//遍历K的集合,得到K的迭代器对象
java.util.Iterator<Integer> iter = set.iterator();
while(iter.hasNext()){
int num = iter.next();
String str = map.get(num);
System.out.println(num+"\t"+str);
}
}
}
运行结果:
0学生0
11000学生11
13000学生13
2000学生2
4000学生4
6000学生6
8000学生8
10000学生10
1000学生1
12000学生12
3000学生3
14000学生14
5000学生5
7000学生7
9000学生9
从上面的运行结果可知,映射也是种无序的集合。
像上面的集合一样向映射中添加重复相同的元素,代码如下:
public class HashMapTest {
//主函数
public static void main(String args[]){
//创建一个映射对象
java.util.HashMap<Integer,String> map = new java.util.HashMap<Integer,String>();
//装入键值对
for (int i=0;i<10;i++){
int key = i*1000;
String value = "学生"+i;
map.put(key, value);
}
map.put(1234,"新同学");
map.put(1234,"新来的");
map.put(4321,"新来的");
map.put(4321,"新同学");
//遍历
//得到K的set集合
java.util.Set<Integer> set = map.keySet();
//遍历K的集合,得到K的迭代器对象
java.util.Iterator<Integer> iter = set.iterator();
while(iter.hasNext()){
int num = iter.next();
String str = map.get(num);
System.out.println(num+"\t"+str);
}
}
}
运行结果:
0学生0
1000学生1
2000学生2
3000学生3
4000学生4
1234新来的
5000学生5
6000学生6
7000学生7
8000学生8
9000学生9
4321新同学
从运行结果来看,映射的元素也是不可重复的如果加入相同的键值对时,则会替换掉原来的键值对。总结来说,映射的特点是:一个K对应一个V,K是一个set集合,是不可重复的,无序的,如果加入相同K的键值对时,则会替换原来的键值对。
以上三种集合框架的应用是很广的,比如对一个整型数组进行去重复排序,就可以用Set对数组去重复,然后在用其他排序方法对去重复的数组进行排序。要统计一个数组中的相同元素的个数,就可以用Map对数组进行操作,返回数组元素及其出现的次数。具体代码如下:
public class Test {
public static void main(String args[]){
//初始化一个数组
int[] array = {2,3,5,3,7,4,9,3,2,1,8,6,3,8,7,3,2,1,9,};
//创建Test类对象
Test ft = new Test();
int[] ar = ft.reSet(array);
for (int i=0;i<ar.length;i++){
System.out.print(ar[i]+"\t");
}
java.util.HashMap<Integer,Integer> map = ft.reput(array);
ft.print(map);
}
/*
* 去掉数组中重复的元素并排序的方法
*/
public int[] reSet(int[] arr) {
// 创建HashSet的对象
java.util.HashSet<Integer> set = new java.util.HashSet<Integer>();
// 遍历数组,将数组中的元素加到HashSet中
for (int i = 0; i < arr.length; i++) {
// 将数组的元素添加到集合中
set.add(arr[i]);
}
// 再将集合中的元素保存回数组中
// 实例化一个数组
int[] temps = new int[set.size()];
// 得到迭代器对象
java.util.Iterator<Integer> ter = set.iterator();
int k=0;
while (ter.hasNext()) {
temps[k] = ter.next();
k++;
}
// 冒泡排序
for (int i = 0; i < temps.length; i++) {
for (int j = i + 1; j < temps.length; j++) {
if (temps[i] > temps[j]) {
int temp = temps[i];
temps[i] = temps[j];
temps[j] = temp;
}
}
}
return temps;
}
/*
* 返回数组中相同元素的个数的方法
*/
public java.util.HashMap<Integer,Integer> reput(int[] arr){
//创建映射对象
java.util.HashMap<Integer,Integer> map = new java.util.HashMap<Integer,Integer>();
int[] key = reSet(arr);
//实例化一个数组
int[] value = new int[key.length];
for (int i=0;i<key.length;i++){
for (int j=0;j<arr.length;j++){
if (key[i]==arr[j]){
value[i]++;
}
}
}
for (int i=0;i<key.length;i++){
map.put(key[i], value[i]);
}
return map;
}
//打印映射的方法
public void print(java.util.HashMap<Integer,Integer> map){
//遍历
//得到K的set集合
java.util.Set<Integer> set = map.keySet();
//遍历K的集合,得到K的迭代器对象
java.util.Iterator<Integer> iter = set.iterator();
while(iter.hasNext()){
int num = iter.next();
int str = map.get(num);
System.out.println(num+"\t"+str);
}
}
}
运行结果:
12345678
9
12
23
35
41
51
61
72
82
92