java基础-API-集合框架-Collection
2015-08-23 20:36
666 查看
一、集合体系概述
1、为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
2、数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
3、集合类的特点
集合中存储的都是对象的引用(地址)。
4、集合框架
![](http://img.blog.csdn.net/20150823205552567)
为什么会出现这么多容器?
因为每一个容器对数据的存储方式不同。存储方式称之为:数据结构
Collection是集合框架中的根接口。其下有两个常用子接口:List(列表),Set(集)。
所属关系:Collection
|--List //元素是有序的,元素可以重复。因为该集合体系有索引。
|--Set //元素是无序的,元素不可以重复。
二、Collection的共性方法
1、添加元素
add(Object obj); //add方法的参数类型是Object。以便于接收任意类型对象。
2、获取个数,集合长度
size();
3、删除元素
remove(Object obj);
clear();//清空集合
4、判断元素
contains(Object obj);//判断是否存在obj这个元素
isEmpty();//是否为空
5、取交集
retainAll(另一集合);//调用者只保留两集合的共性元素。
6、获取元素
迭代器:Iterator--其实就是集合的取出元素的方式。
方法:hasNext();//如果仍有元素可以迭代,返回true。
next();//返回迭代的下一个元素。
remove();//移除最后一个元素。
方式一: Iterator it = al2.iterator();//获取迭代器,用于取出集合中的元素。 while (it.hasNext()) { sop("al2:"+it.next()); }
方式二: for (Iterator it = al2.iterator(); it.hasNext(); )
{
sop("al2:"+it.next());
}
注意:在迭代式循环中next调用一次,就要hasNext判断一次。
代码示例:
运行结果:
![](http://img.blog.csdn.net/20150823205645152)
三、List
1、 List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
|--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
|--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。
2、List特有方法:凡是可以操作角标的方法都是该体系特有的方法。
a.增:add(index,element);
b.删:remove(index);
c.改:set(index,element);
d.查:get(index);
subList(from,to);
listIterator();
ListIterator:List集合特有的迭代器,是Iterator的子接口
ListIterator特有的方法:
add(obj);//增加
set(obj);//修改为obj
hasPrevious();//判断前面有没有元素
previous();//取前一个元素
代码示例:
运行结果:
![](http://img.blog.csdn.net/20150823205716540)
3、ArrayList
ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
例:去除ArrayList集合中的重复元素。
运行结果:
![](http://img.blog.csdn.net/20150823205744260)
例:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。如存人对象,同姓名同年龄视为同一个人。
运行结果:
![](http://img.blog.csdn.net/20150823205807564)
4、LinkedList
LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
LinkedList特有方法:
在JDK1.6以后,出现了替代方法。
addFirst(); offFirst();
addLast(); offLast();
getFirst(); peekFirst();
getLast(); peekLast();
获取元素,但不删除元素。 获取元素,但不删除元素。
如果集合中没有元素, 如果集合中没有元素,
会出现NoSuchElementException。 会返回null。
removeFirst(); pollFirst();
removeLast(); pollLast();
获取元素,并删除元素。 获取元素,并删除元素。
如果集合中没有元素 如果集合中没有元素,
会出现NoSuchElementException。 会返回null。
例: 使用LinkedList模拟一个堆栈或者队列数据结构。
5、Vector
Vector:底层是数组数据结构。线程同步。被ArrayList替代了。
例:
运行结果:
![](http://img.blog.csdn.net/20150823205841967)
四、Set
1、Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层数据结构是哈希表。线程不同步。保证元素唯一性的依据:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。
2、Set集合的功能和Collection是一致的。
3、HashSet
HashSet:底层数据结构是哈希表。线程不同步。
保证元素唯一性的依据:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
注意:对于判断元素是否存在contains,以及删除remove等操作,依赖的方法是元素的hashcode和equals方法。
代码示例:
4、TreeSet
TreeSet:底层数据结构是二叉树。可以对Set集合中的元素进行排序。默认按照字母的自然排序。
保证元素唯一性的依据:compareTo方法return 0。
二叉树:
![](http://img.blog.csdn.net/20150823205915669)
TreeSet排序的两种方式
1)第一种排序方式:自然排序
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。
2)第二种方式:比较器
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。
当两种排序都存在时,以比较器为主。
代码示例:
例:按照字符串长度排序
运行结果:
![](http://img.blog.csdn.net/20150823205950561)
五、泛型
1、泛型概述
泛型:JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。
泛型格式: 通过<>来定义要操作的引用数据类型
好处:
a、将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时期的问题减少,安全。
b、避免了强制转化麻烦。
2、泛型使用
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要见到<>就要定义泛型。
其实<>就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
代码示例:
运行结果:
![](http://img.blog.csdn.net/20150823210011142)
运行结果中注意:使用了未经检查或不安全的操作的信息不见了。
3、泛型类、泛型方法、泛型接口
a.什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,
早期定义Object来完成扩展。现在定义泛型来完成扩展。
泛型类定义的泛型,在整个类中有效。在泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
b.为了让不同方法可以操作不同类型,而且类型还不确定。
那么可以将泛型定义在方法上。
c.特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
代码示例:
运行结果:
![](http://img.blog.csdn.net/20150823210029001)
4、泛型限定
?:通配符。也可以理解为占位符。
泛型的限定:
? extends E:可以接收E类型或E的子类型。上限。
?super E:可以接收E类型或E的父类型。下限。
代码示例:
1、为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
2、数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
3、集合类的特点
集合中存储的都是对象的引用(地址)。
4、集合框架
为什么会出现这么多容器?
因为每一个容器对数据的存储方式不同。存储方式称之为:数据结构
Collection是集合框架中的根接口。其下有两个常用子接口:List(列表),Set(集)。
所属关系:Collection
|--List //元素是有序的,元素可以重复。因为该集合体系有索引。
|--Set //元素是无序的,元素不可以重复。
二、Collection的共性方法
1、添加元素
add(Object obj); //add方法的参数类型是Object。以便于接收任意类型对象。
2、获取个数,集合长度
size();
3、删除元素
remove(Object obj);
clear();//清空集合
4、判断元素
contains(Object obj);//判断是否存在obj这个元素
isEmpty();//是否为空
5、取交集
retainAll(另一集合);//调用者只保留两集合的共性元素。
6、获取元素
迭代器:Iterator--其实就是集合的取出元素的方式。
方法:hasNext();//如果仍有元素可以迭代,返回true。
next();//返回迭代的下一个元素。
remove();//移除最后一个元素。
方式一: Iterator it = al2.iterator();//获取迭代器,用于取出集合中的元素。 while (it.hasNext()) { sop("al2:"+it.next()); }
方式二: for (Iterator it = al2.iterator(); it.hasNext(); )
{
sop("al2:"+it.next());
}
注意:在迭代式循环中next调用一次,就要hasNext判断一次。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 1,add方法的参数类型是Object。以便于接收任意类型对象。 2,集合中存储的都是对象的引用(地址)。 3,迭代器:其实就是集合的取出元素的方式。 */ classCollectionDemo { publicstaticvoid main(String[] args) { //创建一个集合容器。使用Collection接口的子类。ArrayList ArrayList al1 =newArrayList(); ArrayList al2 =newArrayList(); //1、添加元素。 al1.add("java01");//add(Object obj); al1.add("java02"); al1.add("java03"); al1.add("java04"); al2.add("java01");//add(Object obj); al2.add("java02"); al2.add("java05"); al2.add("java06"); //打印集合 sop("原集合al1:"+al1); //2、获取个数。集合长度。 sop("al1:size = "+al1.size()); //3、删除元素 al1.remove("java03"); //al.clear();//清空集合。 sop("新集合al1:"+al1); //4、判断元素。 sop("java01是否存在于al1:"+al1.contains("java01")); sop("al1集合是否为空:"+al1.isEmpty()); //5、取交集。al1中只会保留al2中相同的元素。 al1.retainAll(al2); //al1.removeAll(al2); sop("al2"+al2); sop("al1与al2取交集后的al1:"+al1); //获取元素 Iterator it = al2.iterator();//获取迭代器,用于取出集合中的元素。 while(it.hasNext()) { sop("al2:"+it.next()); } /*for (Iterator it = al2.iterator(); it.hasNext(); ) { sop("al2:"+it.next()); }*/ } publicstaticvoid sop(Object obj) { System.out.println(obj); } }</span>
运行结果:
三、List
1、 List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
|--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
|--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。
2、List特有方法:凡是可以操作角标的方法都是该体系特有的方法。
a.增:add(index,element);
b.删:remove(index);
c.改:set(index,element);
d.查:get(index);
subList(from,to);
listIterator();
ListIterator:List集合特有的迭代器,是Iterator的子接口
ListIterator特有的方法:
add(obj);//增加
set(obj);//修改为obj
hasPrevious();//判断前面有没有元素
previous();//取前一个元素
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">/* Collection |--List:元素是有序的,元素可以重复。因为该集合体系有索引。 |--Set:元素是无序的,元素不可以重复。因为该集合体系没有索引。 List: 特有方法:凡是可以操作角标的方法都是该体系特有的方法。 增:add(index,element); add(index,Collection); 删:remove(index); 改:set(index,element); 查:get(index); subList(from,to); listIterator(); List集合特有的迭代器:ListIterator是Iterator的子接口 ListIterator特有的方法: add(obj);//增加 set(obj);//修改 hasPrevious();//判断前面有没有元素 previous();//取前一个元素 */ import java.util.*; classListDemo { publicstaticvoid main(String[] args) { ArrayList al =newArrayList(); //添加元素。 al.add("java01");//add(Object obj); al.add("java02"); al.add("java03"); //打印集合 sop("原集合al:"+al); //在指定位置添加元素 al.add(1,"java08"); sop("在指定位置1添加元素:"+al); //删除指定位置元素 al.remove(2); sop("删除指定位置2元素:"+al); //修改指定位置元素。 al.set(2,"java05"); sop("修改指定位置2元素:"+al); //通过角标获取元素 sop("通过角标获取元素get(1):"+al.get(1)); //通过角标遍历所有元素 sop("遍历获取所有元素:"); for(int x=0; x<al.size(); x++) { sop("al("+x+")="+al.get(x)); } //通过indexOf获取对象的位置 sop("index="+al.indexOf("java05")); //返回子列表 List sub = al.subList(1,3); sop("sub="+sub); //演示列表迭代器 Iterator it = al.iterator(); while(it.hasNext()) { //sop("al:"+it.next()); Object obj = it.next(); if(obj.equals("java01")) //al.add("java009");//发生ConcurrentModificationException异常。 it.remove();//Iterator方法有限,只有hasNext(); next(); remove();方法 } sop(al); //如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。 ListIterator li = al.listIterator(); while(li.hasNext()) { Object obj = li.next(); if(obj.equals("java05")) li.add("java09");//添加 } sop(al); while(li.hasPrevious())//向前逆向遍历 { Object obj = li.previous();//取前一个元素 if(obj.equals("java09")) li.set("java0007");//修改 } sop(al); } publicstaticvoid sop(Object obj) { System.out.println(obj); } }</span>
运行结果:
3、ArrayList
ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
例:去除ArrayList集合中的重复元素。
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 去除ArrayListTest集合中的重复元素 */ classArrayListTest { publicstaticvoid main(String[] args) { ArrayList al =newArrayList(); //添加元素。 al.add("java01");//add(Object obj); al.add("java02"); al.add("java02"); al.add("java03"); al.add("java03"); sop(al); al = singleElement(al); sop(al); } publicstaticArrayList singleElement(ArrayList al) { //定义一个临时容器 ArrayList newAl =newArrayList(); Iterator it = al.iterator(); while(it.hasNext()) { Object obj = it.next(); if(!newAl.contains(obj)) { newAl.add(obj); } } return newAl; } publicstaticvoid sop(Object obj) { System.out.println(obj); } }</span>
运行结果:
例:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。如存人对象,同姓名同年龄视为同一个人。
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。如存人对象,同姓名同年龄视为同一个人 List集合判断元素是否相同,依据是元素的equals方法。 contains 底层调用的是equals方法,所以要重写equals方法。 */ classPerson { privateString name; privateint age; Person(String name,int age) { this.name = name; this.age = age; } publicboolean equals(Object obj) { if(!(obj instanceofPerson)) returnfalse; Person p =(Person)obj; //System.out.println(this.name+"..."+p.name); returnthis.name.equals(p.name)&&this.age == p.age; } publicString getName() { return name; } publicint getAge() { return age; } } classArrayListTest1 { publicstaticvoid main(String[] args) { ArrayList al =newArrayList(); al.add(newPerson("lisi01",11));//al.add(Object obj);//Object obj = new Person("lisi01",11); al.add(newPerson("lisi02",12)); al.add(newPerson("lisi02",12)); al.add(newPerson("lisi03",13)); al.add(newPerson("lisi04",14)); al.add(newPerson("lisi04",14)); sop("原ArrayList集合:"); printAl(al); al = singleElement(al); sop("新ArrayList集合:"); printAl(al); } publicstaticvoid printAl(ArrayList al) { Iterator it = al.iterator(); while(it.hasNext()) { //Object obj = it.next(); Person p =(Person)it.next(); sop(p.getName()+"::"+p.getAge()); } } publicstaticArrayList singleElement(ArrayList al) { //定义一个临时容器 ArrayList newAl =newArrayList(); Iterator it = al.iterator(); while(it.hasNext()) { Object obj = it.next(); if(!newAl.contains(obj)) { newAl.add(obj); } } return newAl; } publicstaticvoid sop(Object obj) { System.out.println(obj); } }</span>
运行结果:
4、LinkedList
LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
LinkedList特有方法:
在JDK1.6以后,出现了替代方法。
addFirst(); offFirst();
addLast(); offLast();
getFirst(); peekFirst();
getLast(); peekLast();
获取元素,但不删除元素。 获取元素,但不删除元素。
如果集合中没有元素, 如果集合中没有元素,
会出现NoSuchElementException。 会返回null。
removeFirst(); pollFirst();
removeLast(); pollLast();
获取元素,并删除元素。 获取元素,并删除元素。
如果集合中没有元素 如果集合中没有元素,
会出现NoSuchElementException。 会返回null。
例: 使用LinkedList模拟一个堆栈或者队列数据结构。
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 使用LinkedList模拟一个堆栈或者队列数据结构。 堆栈:先进后出 如同一个杯子。 队列:先进先出 First in First out FIFO 如同一个水管。 */ classDuiLie { privateLinkedList link; DuiLie() { link =newLinkedList(); } publicvoid myAdd(Object obj) { link.addFirst(obj); } publicObject myGet() { return link.removeLast();//return link.removeFirst();就是堆栈 } publicboolean isNull() { return link.isEmpty(); } } classLinkedListDemo { publicstaticvoid main(String[] args) { DuiLie dl =newDuiLie(); dl.myAdd("java01"); dl.myAdd("java02"); dl.myAdd("java03"); dl.myAdd("java04"); while(!dl.isNull()) { sop(dl.myGet()); } } publicstaticvoid sop(Object obj) { System.out.println(obj); } }<span style="font-family: 'Microsoft YaHei'; color: rgb(190, 190, 197);"> </span></span>
5、Vector
Vector:底层是数组数据结构。线程同步。被ArrayList替代了。
例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 枚举就是Vector特有的取出方式 */ classVectorDemo { publicstaticvoid main(String[] args) { Vector v =newVector(); v.add("java01"); v.add("java02"); v.add("java03"); v.add("java04"); Enumeration en = v.elements(); while(en.hasMoreElements()) { System.out.println(en.nextElement()); } } }</span>
运行结果:
四、Set
1、Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层数据结构是哈希表。线程不同步。保证元素唯一性的依据:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。
2、Set集合的功能和Collection是一致的。
3、HashSet
HashSet:底层数据结构是哈希表。线程不同步。
保证元素唯一性的依据:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
注意:对于判断元素是否存在contains,以及删除remove等操作,依赖的方法是元素的hashcode和equals方法。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 将自定义对象作为元素存到HashSet集合中,并去除重复元素。如存人对象,同姓名同年龄视为同一个人 保证元素唯一性的依据:判断元素的hashCode值是否相同。 如果相同,还会继续判断元素的equals方法,是否为true。 注意:对于判断元素是否存在contains,以及删除remove等操作,依赖的方法是元素的hashcode和equals方法。 */ classPerson { privateString name; privateint age; Person(String name,int age) { this.name = name; this.age = age; } publicint hashCode()//重写hashcode { System.out.println(this.name+"...hashcode"); return name.hashCode()+age*39; } publicboolean equals(Object obj)//重写equals { if(!(obj instanceofPerson)) returnfalse; Person p =(Person)obj; System.out.println(this.name+"..."+p.name); returnthis.name.equals(p.name)&&this.age == p.age; } publicString getName() { return name; } publicint getAge() { return age; } } classHashSetDemo { publicstaticvoid main(String[] args) { HashSet hs =newHashSet(); hs.add(newPerson("a1",11)); hs.add(newPerson("a2",12)); hs.add(newPerson("a3",13)); hs.add(newPerson("a2",12)); sop("a1:"+hs.contains(newPerson("a1",11))); sop("a3:"+hs.remove(newPerson("a3",13))); Iterator it = hs.iterator(); while(it.hasNext()) { Person p =(Person)it.next(); sop(p.getName()+"::"+p.getAge()); } } publicstaticvoid sop(Object obj) { System.out.println(obj); } }</span>
4、TreeSet
TreeSet:底层数据结构是二叉树。可以对Set集合中的元素进行排序。默认按照字母的自然排序。
保证元素唯一性的依据:compareTo方法return 0。
二叉树:
TreeSet排序的两种方式
1)第一种排序方式:自然排序
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。
2)第二种方式:比较器
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。
当两种排序都存在时,以比较器为主。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 往TreeSet集合中存储自定义对象学生,并按照学生年龄进行排序。 排序时,当主要条件相同时,一定要判断一下次要条件。 */ classStudentimplementsComparable//该接口强制让学生具备比较性 { privateString name; privateint age; Student(String name,int age) { this.name = name; this.age = age; } publicint compareTo(Object obj)//若想怎么存怎么取,只需返回1;倒序则返回-1即可。 { if(!(obj instanceofStudent)) thrownewRuntimeException("不是学生对象"); Student s =(Student)obj; //System.out.println(this.name+"...compareto"+s.name); if(this.age>s.age) return1; if(this.age==s.age) { returnthis.name.compareTo(s.name); } return-1; } publicString getName() { return name; } publicint getAge() { return age; } } classTreeSetDemo { publicstaticvoid main(String[] args) { TreeSet ts =newTreeSet(); ts.add(newStudent("lisi02",22)); ts.add(newStudent("lisi07",20)); ts.add(newStudent("lisi09",19)); ts.add(newStudent("lisi08",19)); ts.add(newStudent("lisi08",19)); Iterator it = ts.iterator(); while(it.hasNext()) { Student stu =(Student)it.next(); sop(stu.getName()+"::"+stu.getAge()); } } publicstaticvoid sop(Object obj) { System.out.println(obj); } } classMyCompareimplementsComparator//构造比较器 { publicint compare(Object o1,Object o2) { Student s1 =(Student)o1; Student s2 =(Student)o2; int num = s1.getName().compareTo(s2.getName()); if(num==0) { return s1.getAge()- s2.getAge(); } return num; } }</span>
例:按照字符串长度排序
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; //按照字符串长度排序 classTreeSetTest { publicstaticvoid main(String[] args) { TreeSet ts =newTreeSet(newStrLenComparator()); ts.add("abd"); ts.add("cc"); ts.add("z"); ts.add("hahaha"); ts.add("zdf"); Iterator it = ts.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } } classStrLenComparatorimplementsComparator { publicint compare(Object o1,Object o2) { String s1 =(String)o1; String s2 =(String)o2; int num =newInteger(s1.length()).compareTo(newInteger(s2.length())); if(num ==0) return s1.compareTo(s2); return num; } }</span>
运行结果:
五、泛型
1、泛型概述
泛型:JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。
泛型格式: 通过<>来定义要操作的引用数据类型
好处:
a、将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时期的问题减少,安全。
b、避免了强制转化麻烦。
2、泛型使用
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要见到<>就要定义泛型。
其实<>就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; /* 泛型:JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。 好处: 1,将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时期的问题减少,安全。 2,避免了强制转化麻烦。 */ classGenericDemo { publicstaticvoid main(String[] args) { ArrayList<String> al =newArrayList<String>();//当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。 al.add("abc01"); al.add("abc002"); al.add("abc0003"); //al.add(4);//编译通过,运行出现ClassCastException Iterator<String> it = al.iterator();//当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。 while(it.hasNext()) { //String s = (String)it.next();//避免了强制转化麻烦。 String s = it.next(); System.out.println(s+"::"+s.length()); } } }</span>
运行结果:
运行结果中注意:使用了未经检查或不安全的操作的信息不见了。
3、泛型类、泛型方法、泛型接口
a.什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,
早期定义Object来完成扩展。现在定义泛型来完成扩展。
泛型类定义的泛型,在整个类中有效。在泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
b.为了让不同方法可以操作不同类型,而且类型还不确定。
那么可以将泛型定义在方法上。
c.特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">classDemo<T>//泛型类 { publicvoid show(T t) { System.out.println("class show:"+t); } public<T>void print(T t)//泛型方法 { System.out.println("function print:"+t); } publicstatic<T>void method(T t)//静态方法泛型 { System.out.println("static method:"+t); } } interfaceInter<T>//泛型接口 { void show(T t); } classInterImpl<T>implementsInter<T>//泛型接口 { publicvoid show(T t) { System.out.println("interface show:"+t); } } classGenericDemo1 { publicstaticvoid main(String[] args) { Demo<String> d =newDemo<String>(); Demo<Integer> d1 =newDemo<Integer>(); d.show("haha"); d1.show(0); d.print("hehe"); d.print(newInteger(4)); d.method("heihei"); d.method(8); InterImpl<String> i =newInterImpl<String>(); i.show("hiahia"); InterImpl<Integer> i1 =newInterImpl<Integer>(); i1.show(12); } }<span style="font-family: 'Microsoft YaHei'; color: rgb(190, 190, 197);"> </span></span>
运行结果:
4、泛型限定
?:通配符。也可以理解为占位符。
泛型的限定:
? extends E:可以接收E类型或E的子类型。上限。
?super E:可以接收E类型或E的父类型。下限。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*; classGenericDemo2 { publicstaticvoid main(String[] args) { ArrayList<Person> al =newArrayList<Person>(); al.add(newPerson("abc01")); al.add(newPerson("abc002")); al.add(newPerson("abc0003")); ArrayList<Student> al1 =newArrayList<Student>(); al1.add(newStudent("abc---01")); al1.add(newStudent("abc---002")); al1.add(newStudent("abc---0003")); printColl(al); printColl(al1); } publicstaticvoid printColl(ArrayList<?extendsPerson> al) { Iterator<?extendsPerson> it = al.iterator(); while(it.hasNext()) { System.out.println( it.next().getName()); } } } classPerson { privateString name; Person(String name) { this.name = name; } publicString getName() { return name; } } classStudentextendsPerson { Student(String name) { super(name); } }</span>
相关文章推荐
- Spring配置文件解析--依赖注入
- [笔记][Java7并发编程实战手册]3.7 并发阶段任务中的阶段切换phaser
- Java反射机制初涉
- java基础关于java排序(一)
- Java多线程通信机制
- Java多线程的用法详解
- 像素翻转(Java)
- Java策略设计模式感悟
- java多线程详细总结
- Java初级培训笔记------IO流(2)
- java获取文件编码
- Java 四大域对象总结
- Spring配置文件解析--bean属性
- Java修饰符关键词大全
- Spring学习之Aop的基本概念
- java基础-API-String类、基本数据类型对象包装类
- java线 生产者和消费者
- Java内存问题的一些见解
- 【Spring】初始化Spring IoC容器(非Web应用),并获取Bean
- Java I/O 操作及优化建议