import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
/**
* 泛型:
* jdk1.5出现的安全机制。
* 好处:
* 1.将运行时期的问题ClassCastException转到了编译时期。
* 2.避免了强制转换的麻烦。
* <>什么时候用:当操作的引用数据类型不确定的时候。就使用<>。将要操作的引用数据类型传入即可。
* 其实<>就是一个用于接收具体引用数据类型的参数范围。
* 在程序中只要用到了带有<>的类或接口就要明确传入的具体引用数据类型。
*
* 泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。
* 运行时会将泛型去掉,生成的class文件中是不带泛型的,这称之为“泛型的擦除”。
* 为什么擦除呢?为了兼容运行的类加载器。
*
* 泛型的补偿:在运行时,通过获取元素的类型进行转换动作,不用使用者再强制转换了。
*/
class Person implements Comparable<Person>{//<>内指定需要比较的对象
private String name;
private int age;
public int compareTo(Person obj) {
// Person p = (Person)obj;
int temp = this.age-obj.age;
return temp==0?this.name.compareTo(obj.name):temp;
}
Person(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
}
//没有使用泛型的Tool类
class Tool{
private Object object;
public Object getObject() {
return this.object;
}
public void setObject(Object object) {
this.object = object;
}
}
//在jdk1.5使用泛型来接受类中要操作的引用数据类型。
//泛型类。什么时候用?当类中操作的引用数据类型不确定时就用泛型来表示。
class Tool_<QQ>{
private QQ q;
public QQ getQQ(){
return this.q;
}
public void setQQ(QQ object){
this.q = object;
}
public void show(QQ object){
System.out.println("show:"+object);
}
//将泛型定义在方法上
public <W> void show1(W object){
System.out.println("show1:"+object);
}
public static <W> void method(W object) {
//当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能在方法上定义泛型
System.out.println("method:"+object);
}
}
public class packDemo{
public static void main(String[] args){
genericDemo_4();
}
public static void genericDemo_1(){
ArrayList<String> al = new ArrayList<String>();
al.add("hello");
al.add("world");
al.add("this");
Iterator it = al.iterator();
while(it.hasNext()){
// String str = (String)it.next();
System.out.println(it.next());
}
}
public static void genericDemo_2(){
TreeSet<Person> ts = new TreeSet<Person>();//Person类需要基础comparable并覆盖compareTo方法
ts.add(new Person("pp", 24)); //也可定义比较器,在()中new,按其他规则排序
ts.add(new Person("zz", 23)); //泛型里面只能是引用数据类型,不能是int类,可以是Integer
ts.add(new Person("ww", 25));
Iterator<Person> it = ts.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
/*
泛型类
*/
public static void genericDemo_3(){
//未使用泛型类
Tool tool = new Tool();
tool.setObject(new Person("pp", 24));
Person person = (Person)tool.getObject();
System.out.println(person.getName());
//使用泛型类之后:
Tool_<Person> tool_ = new Tool_<Person>();
tool_.setQQ(new Person("kpp", 24));
Person person_ = tool_.getQQ();
System.out.println(person_.getName());
}
public static void genericDemo_4(){
Tool_<Person> tool_ = new Tool_<Person>();
tool_.setQQ(new Person("kpp", 24));
tool_.show1(tool_.getQQ());//show:mypackage.Person@54bedef2
tool_.show1("object");
tool_.method("hello");
/*
Integer a = new Integer(1);
Integer a2 = -127;
//直接=没有new对象时,-127~128之间会自动拆箱为int类型,范围之外会自动装箱
Integer a3 = -127;
Integer a1 = new Integer(1);
int b = -1;
System.out.println(a==b);
System.out.println(a==a1);
System.out.println(a2==a3);
*/
}
}
泛型接口
//泛型接口,将泛型定义在接口上.
interface Inter<T>{
public void show(T t);
}
class InterImpl implements Inter<String>{
public void show(String str) {
System.out.println("interimpl:"+str);
}
}
class InterImpl_2<Q> implements Inter<Q>{
public void show(Q q) {
System.out.println("InterImpl_2:"+q);
}
}
public class packDemo{
public static void main(String[] args){
// genericDemo_4();
InterImpl ii = new InterImpl();
ii.show("hello");
InterImpl_2<String> i2 = new InterImpl_2();
i2.show("i2:hello");
}
}
泛型限定
class Person{//<>内指定需要比较的对象
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString() {
return "person:"+name;
}
}
//泛型限定
public static void genericDemo_5() {
ArrayList<String> al = new ArrayList<String>();
al.add("abc");
al.add("hcv");
al.add("jhg");
printCollection2(al);
ArrayList al2 = new ArrayList();
al2.add(2);
al2.add(3);
al2.add(4);
printCollection2(al2);
ArrayList<Person> al_p = new ArrayList<Person>();
al_p.add(new Person("pp", 2));
al_p.add(new Person("zz", 2));
printCollection_person(al_p);
}
//迭代并打印集和中的元素
public static void printCollection(Collection<String> al) {
Iterator<String> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
//泛型的通配符:?
public static void printCollection2(Collection<?> al) {//可以输出不同类型的Collection
Iterator it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
public static <T> void printCollection3(Collection<T> al) {//可以输出不同类型的Collection
Iterator<T> it = al.iterator();
while(it.hasNext()){
T str = it.next();
System.out.println(str);
}
}
public static void printCollection_person(Collection<? extends Person> al) {//泛型限定,只接收person或person子类
Iterator<? extends Person> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
//上限体现:
//一般在存储元素时都使用上限,因为这样都是按照上限类型来运算的,不会出现类型安全隐患(? extends E)
//下限体现:
//通常对集和中的元素取出操作时,可以使用下限。
class Person implements Comparable<Person>{//<>内指定需要比较的对象
String name;
int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public int compareTo(Person obj) {
// Person p = (Person)obj;
int temp = this.age-obj.age;
return temp==0?this.name.compareTo(obj.name):temp;
}
public String toString() {
return "person:"+name+"--"+age;
}
}
class Student extends Person{
int score;
Student(String name,int age,int score){
super(name,age);
this.score = score;
}
}
/**
* class TreeSet<E>{
* Tree(Comparator<? super E> comp);
* }
*/
class compByName implements Comparator<Person>{
//覆盖
public int compare(Person o1,Person o2) {
int temp = o1.name.compareTo(o2.name);
return temp==0?o1.age-o2.age:temp;
}
}
public class packDemo{
public static void main(String[] args){
genericDemo_5();
}
//泛型限定
public static void genericDemo_5() {
TreeSet<Person> al = new TreeSet<Person>();
al.add(new Person("pp", 24));
al.add(new Person("zz", 24));
al.add(new Person("mm", 24));
Iterator it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
TreeSet<Person> al_s = new TreeSet<Person>(new compByName());
al_s.add(new Student("kpp", 24, 78));
al_s.add(new Student("zz", 23, 78));
al_s.add(new Student("as", 25, 78));
al_s.add(new Person("ww", 25));
Iterator it_s = al_s.iterator();
while(it_s.hasNext()){
System.out.println(it_s.next());
}
show(al_s);
}
public static void show(Set<? super Person> al) {
Iterator<? super Person> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
集和的一些技巧:
需要唯一:Set
需要指定顺序:
需要:TreeSet
不需要:HashSet
但是想要有一个和存储一致的顺序(有序):LinkedHashSet
不需要唯一:List
需要频繁增删:
需要:LinkedList
不需要:ArrayList
如何记住每个容器的结构和所属体系:看名字
后缀名是该集和所属名字,前缀名就是该集和的数据结构。
看到Array,想到数组,查询快,有角标。
看到link,想到链表,增删快,add,get remove。
看到Hash,想到哈希表,唯一性,元素需要覆盖hashcode方法和equals方法。
看到tree,想到树,二叉树,排序,两个接口:comparable,Comparator。
通常这些常用的集和容器都是不同步的!