您的位置:首页 > 其它

集合(2)TreeSet , 泛型

2015-07-07 22:57 274 查看

TreeSet: 二叉树数据结构,可以对元素进行排序,不同步的。

如何保证元素唯一性?

参考的就是比较方法的返回值是否是0,是,就是重复元素,不存。

**排序方式:需要元素具备比较功能,所以元素需要实现Comparable接口。

覆盖compareTo方法。

**需求中也有这样一种情况,元素具备的比较功能不是所需要的,也就是说不想按照

自然排序的方法,而是按照自定义的排序方法,对元素就行排序。

而且,存储到TreeSet中的元素万一没有比较功能,该如何排序呢?

这时,就只能用第二种比较方式--让集合具备比较功能。

初始化TreeSet集合时明确一个比较器。

实现Comparator接口,覆盖compare方法 。将Comparator接口的对象

作为参数传递给TreeSet集合的构造器。

比较器更为灵活,自然排序通常作为元素的默认排序。

异常: java.lang.ClassCastException

原因:因为学生要排序,就需要比较,而没有定义比较方法

比较add方法中使用的是Comparable接口的比较方法.

public int compareTo(Object o) //自然排序以年龄升序排序为主,相同则比较姓名

{

/* Student stu =(Student)0;

if(this.age>stu.age)

return 1;

if(this.age<stu<age)

return -1;

return 0; */

int temp=this.age=stu.age;

return temp==0?this.name.compareTo(stu.name):temp;

}

******list ,Set 集合 名称阅读技巧***********

jdk1.2以后出现的集合框架中常用的子类对象,存在规律

前缀名是数据结构名,后缀名是所属体系名。

ArrayList:数组结构。看到数组,就知道查询快,看到List,就知道可以重复。可以增删改查。

LinkedList: 链表结构,增删快。xxxFirst xxxLast

HashSet:哈希表,就要想到元素必须覆盖hashCode equals,不保证有序。看到Set,就知道不可以重复

LinkedHashSet:链表+哈希表。可以实现有序,因为有链表。

TreeSet:二叉树,可以排序。就想要两种比较方式:一种是自然排序Comparable,一种是比较器Comparator

*************Foreach语句*******

JDK1.5特性:

增强for循环。作用:用于遍历collection集合or 数组

格式:

for(元素类型变量:Collection容器or数组)

for(Objecct obj: coll)

{

syso(obj);

}

对于数组的遍历,如果不操作其角标,可以使用增强for,如果要操作角标,使用传统for

高级for中不能对数据进行操作,会报并发异常。

***传统for循环和增强for循环有什么区别呢?

增强for必须有被遍历的目标,该目标只能是Collection or 数组

*****Enumeration接口*************

Enumeration:枚举。

具备枚举取出方式的容器只有Vector。

Vector v =new Vector();

//获取枚举

for(Enumeration en =v.elements();en.hashMoreElements();){

system.out.print(en.nextElement());

}

***************泛型*********************

泛型:

在jdk1.4版本之前,容器什么类型的对象都可以存储。但是在取出时。需要用到对象的特有内容时,需要做向下转型。

但是对象的类型不一致,导致了向下转型发生了ClassCastException 异常。

为了避免这个问题,只能主观上控制,往集合中存储的对象保持一致。

jdk1.5以后解决了该问题,在定义集合时,就直接明确集合中存储元素的具体类型。

这样,编译器在编译时,就可以对集合中存储的对象类型进行检查。

一旦发现类型不匹配,就编译失败。这个技术就是泛型技术。

好处:

1,将运行时期的问题转移到了编译时期,可以更好的让程序员发现问题并解决问题。

2,避免了向下转型的麻烦

总结:泛型就是应用在编译时期的一项安全机制。

泛型的擦除:编译器通过泛型对元素类型进行检查,只要检查通过,就会生成class文件,

但在class文件中,就将泛型标识去掉了。

静态方法是无法访问类上定义的泛型的。如果静态方法需要定义泛型,泛型只能定义在方法上。

泛型的表现:

泛型技术在集合框架中应用的范围很大。

什么时候需要填写泛型呢? 1,只要看到类,或者接口在描述时 右边定义<>,就需要泛型。

其实是,容器在不明确操作元素的类型的情况下,对外提供了一个参数<>。

使用容器时,只要将具体的类型实参传递给该参数即可。

说白了,泛型就是,传递类型参数。

****当要操作的类型不确定的时候,为了扩展,

可以使用Object 类型来完成。

但是这种方式一些小弊端,会出现转型,向下转型容易在运行时期发生ClassCastException。

jdk1.5以后,新的解决方案。

类型不确定时,可以对外提供参数。有使用通过传递参数的形式完成类型的确定。

泛型类: 在类定义时就明确参数。有使用该类的调用者,来传递具体的类型。

通配符:在不明确具体类型的情况下,可以使用通配符来表示。 <?>

泛型的限定:

? extands E : 接收E类型或者E的子类型 // 上限

? super E : 接收E类型或者E的父类型 // 下限

什么时候会用到上限呢?

**一般往集合存储元素时。如果集合定义了E类型通常情况下应该存储E类型的对象

对E的子类型的对象E类型也可以接受,所有这时可以将泛型从E改成 ? extends E .

什么时候用到下限呢?

当从容器中取出元素操作时,可以用E类型接收,也可以用E的父类型接收。 ? super E
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: