------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Java基础学习(集合框架)第十五天
一,集合框架-TreeSet
Set:无序,不可重复元素。
|--HashSet:数据结构式哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的hashCode值是否相同。
如果相同,还会继续判断元素的equals方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:
compareTo方法return 0。
TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
这种方式也称为元素的自然顺序,或者叫做默认顺序。
TreeSet集合的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的。
这时就需要集合自身具备比较性。
在集合初始化时,就有了比较方式。
|--HashSet:数据结构式哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的hashCode值是否相同。
如果相同,还会继续判断元素的equals方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:
compareTo方法return 0。
TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
这种方式也称为元素的自然顺序,或者叫做默认顺序。
TreeSet集合的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的。
这时就需要集合自身具备比较性。
在集合初始化时,就有了比较方式。
注:TreeSet集合内元素必须具备比较性。
代码示例:
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
/*
ts.add("cba");
ts.add("aaa");
ts.add("bca");
ts.add("Dbcd");
Iterator it = ts.iterator();
while(it.hsNext())
{
System.out.println(it.next());
}
*/
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi09",19));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"...."+stu.getAge());
}
}
}
class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
System.out.println("In hashCode.....");
return age;
}
@Override
public boolean equals(Object obj){
System.out.println("in here..........");
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println("in here..........");
return this == s;
}
public int compareTo(Object obj)
{
//return 1;//(03)怎么存就怎么取。
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println(this.name+"....compareto...."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
当元素自身不具备比较性,或者具备的比较性不是所需的。
这时需要让容器自身具备比较性。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
当两种排序都存在时,以比较器为主。
定义一个类,实现Comparator接口,覆盖compare方法。
代码示例:
import java.util.*;
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new MyCompare());
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi04",40));
ts.add(new Student("lisi09",19));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"...."+stu.getAge());
}
}
}
class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)
{
//return 1;//(03)怎么存就怎么取。
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println(this.name+"....compareto...."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)//Comparator里是compare方法,Comparable里是compareTo方法。
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int num = s1.getName().compareTo(s2.getName());
if(num==0)
{
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
}
return num;
}
}
泛型:JDK1.5版本以后出现的特性。用于解决安全问题,是一个安全机制。
好处:
1,将运行时期出现的问题ClassCastException,转移到了编译时期
方便于程序员解决问题。让运行时问题减少,安全。
2,避免了强制转换的麻烦。
泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,
只要见到<>就要定义泛型。
其实<>就是用来接收类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
代码示例:
class GenericDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc01");
al.add("abc01");
al.add("abc01");
al.add(4);//al.add(new Ineger(4));
Iterator<String> it = al.iterator();
while(it.hasNext())
{
String s = /*(String)*/it.next();
System.out.println(s+":"+s.length());
}
}
}
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,
早期定义Object来完成扩展。
现在定义泛型来完成扩展。
当类中要操作的引用数据类型不确定的时候,
早期定义Object来完成扩展。
现在定义泛型来完成扩展。
代码示例:
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
}
泛型类定义的泛型,在整个类中有效,如果被方法使用,
那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定。
那么可以将泛型定义在方法上。
那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定。
那么可以将泛型定义在方法上。
代码示例:
/*
特殊之处:
静态方法不可以访问类上的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
*/
class Demo<T>
{
public <T> void show(T t)
{
System.out.println("show:"+t);
}
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
public static <W> void method(W w)
{
System.out.println("method:"+w);
}
}
class GenericDemo4
{
public static void main(String[] args)
{
Demo <String> d = new Demo<String>();
d.show("haha");
//d.show(4);
d.print(5);
d.print("woqu");
Demo.method("hahahhaha");
/*
Demo d = new Demo();
d.show("haha");
d.show(new Integer(4));
d.print("heihe");
*/
/*
Demo<Integer> d = new Demo<Integer>();
d.show(new Integer(4));
d.print(90);
Demo<String> d1 = new Demo<String>();
d1.print("hhha");
d1.show(5);
*/
}
}
五,泛型限定
?通配符。也可以理解为占位符。
泛型限定;
? extends E : 可以接收E类型或者E的子类型。上限。
? super E : 可以接收E类型或者E的父类型。 下限。
泛型限定;
? extends E : 可以接收E类型或者E的子类型。上限。
? super E : 可以接收E类型或者E的父类型。 下限。
代码示例:
public static void printColl(ArrayList<? extends Person> al)
{
Iterator<? extends Person> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}