JDK1.5新特性

泛型(Genrics

 

所谓泛型就是变量类型的参数化

 

泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptons的可能。

 

jdk1.5中,你可以声明一个集合将接收/返回的对象的类型。

 

泛型的ArrayList

public class GenericTest1

{

    public static void main(String[] args)

    {

       List<String> list = new ArrayList<String>();

       list.add("aaa");

       list.add("bbb");

       list.add("ccc");

       list.add("ddd");

      

       for(Iterator<String> iter = list.iterator(); iter.hasNext();)

       {

           String val = iter.next();

           System.out.println(val);

       }

    }

}

 

泛型的LinkedList

public class GenericTest2

{

    public static void main(String[] args)

    {

       List<String> list = new LinkedList<String>();

      

       list.add("aaa");

       list.add("bbb");

       list.add("ccc");

       list.add("ddd");

      

       for(Iterator<String> iter = list.iterator(); iter.hasNext();)

       {

           String val = iter.next();

           System.out.println(val);

       }

    }

}

 

泛型的HashSet

public class GenericTest3

{

    public static void main(String[] args)

    {

       Set<String> set = new HashSet<String>();

      

       set.add("aaa");

       set.add("bbb");

       set.add("ccc");

       set.add("ddd");

      

       for(Iterator<String> iter = set.iterator(); iter.hasNext();)

       {

           String val = iter.next();

           System.out.println(val);

       }

    }

}

 

泛型的HashMap

public class GenericTest4

{

    public static void main(String[] args)

    {

       Map<String,String> map = new HashMap<String,String>();

      

       map.put("a","aaa");

       map.put("b","bbb");

       map.put("c","ccc");

       map.put("d","ddd");

      

       Set<String> set = map.keySet();

      

       for(Iterator<String> iter = set.iterator(); iter.hasNext();)

       {

           String key = iter.next();

           String val = map.get(key);

           System.out.println(key + ":" + val);

       }

      

       System.out.println("-----------------------");

      

       Set<Map.Entry<String,String>> set2 = map.entrySet();

      

       for(Iterator<Map.Entry<String,String>> iter = set2.iterator(); iter.hasNext();)

       {

           Map.Entry<String,String> entry = iter.next();

           String key = entry.getKey();

           String val = entry.getValue();

           System.out.println(key + ":" + val);

       }

      

    }

}

 

如果使用泛型,只要代码在编译时没有出现警告,就不会遇到ClassCastException

 

自定义一个简单的泛型类

public class GenericTest

{

    public static void main(String[] args)

    {

       Foo<Integer> f1 = new Foo<Integer>();

       Foo<Boolean> f2 = new Foo<Boolean>();

      

       f1.setFoo(new Integer(3));

       f2.setFoo(new Boolean(true));

      

       System.out.println(f1.getFoo());

       System.out.println(f2.getFoo());

    }

}

 

class Foo<T>

{

    private T foo;

 

    public T getFoo()

    {

       return foo;

    }

 

    public void setFoo(T foo)

    {

       this.foo = foo;

    }

}

 

两个泛型参数的使用和一个参数的使用类似。

public class GenericTest2

{

    public static void main(String[] args)

    {

       FooTest<Integer,Boolean> foo = new FooTest<Integer, Boolean>();

      

       foo.setFoo1(new Integer(3));

       foo.setFoo2(new Boolean(false));

      

       System.out.println(foo.getFoo1());

       System.out.println(foo.getFoo2());

    }

}

 

class FooTest<T,K>

{

    private T foo1;

    private K foo2;

    public T getFoo1()

    {

       return foo1;

    }

    public void setFoo1(T foo1)

    {

       this.foo1 = foo1;

    }

    public K getFoo2()

    {

       return foo2;

    }

    public void setFoo2(K foo2)

    {

       this.foo2 = foo2;

    }

}

 

泛型数组

public class Generic3<T>

{

    private T[] foo;

 

    public T[] getFoo()

    {

       return foo;

    }

 

    public void setFoo(T[] foo)

    {

       this.foo = foo;

    }

   

    public static void main(String[] args)

    {

       Generic3<String> arr = new Generic3<String>();

      

       String[] str1 = {"hello","world","welcome"};

       String[] str2 = null;

      

       arr.setFoo(str1);

       str2 = arr.getFoo();

      

       for(String s : str2)

       {

           System.out.println(s);

       }

    }

}

 

泛型定义一个简单的集合

@SuppressWarnings("unchecked")

public class SimpleCollection<T>

{

    private T[] arr;

    private int index = 0;

 

    public SimpleCollection()

    {

       arr = (T[]) new Object[10];

    }

 

    public SimpleCollection(int capacity)

    {

       arr = (T[]) new Object[capacity];

    }

 

    public void add(T t)

    {

       arr[index++] = t;

    }

 

    public int getLength()

    {

       return this.index;

    }

 

    public T get(int i)

    {

       return arr[i];

    }

 

    public static void main(String[] args)

    {

       SimpleCollection<Integer> col = new SimpleCollection<Integer>();

 

       for (int i = 0; i < 10; i++)

       {

           col.add(new Integer(i));

       }

 

       for (int i = 0; i < col.getLength(); i++)

       {

           System.out.println(col.get(i));

       }

    }

}

 

将一个泛型对象组合到另一个类中

public class GenericFoo<T>

{

    private Generic<T> warpper;

 

    public Generic<T> getWarpper()

    {

       return warpper;

    }

 

    public void setWarpper(Generic<T> warpper)

    {

       this.warpper = warpper;

    }

   

    public static void main(String[] args)

    {

       Generic<Integer> g1 = new Generic<Integer>();

       g1.setFoo(new Integer(20));

      

       GenericFoo<Integer> gf = new GenericFoo<Integer>();

       gf.setWarpper(g1);

      

       Generic<Integer> g2 = gf.getWarpper();

       System.out.println(g2.getFoo());

    }

}

 

class Generic<T>

{

    private T foo;

 

    public T getFoo()

    {

       return foo;

    }

 

    public void setFoo(T foo)

    {

       this.foo = foo;

    }

}

 

泛型集合中使用自定义类

public class Generic2

{

    public static void main(String[] args)

    {

       List<Person> list = new ArrayList<Person>();

      

       list.add(new Person("bob",20,"us"));

       list.add(new Person("jack",23,"uk"));

       list.add(new Person("Mike",25,"cn"));

      

       for(Iterator<Person> iter = list.iterator(); iter.hasNext();)

       {

           Person p = iter.next();

           System.out.println(p);

       }

    }

}

 

class Person

{

    private String name;

    private int age;

    private String address;

    public Person(String name, int age, String address)

    {

       super();

       this.name = name;

       this.age = age;

       this.address = address;

    }

    public String getName()

    {

       return name;

    }

    public void setName(String name)

    {

       this.name = name;

    }

    public int getAge()

    {

       return age;

    }

    public void setAge(int age)

    {

       this.age = age;

    }

    public String getAddress()

    {

       return address;

    }

    public void setAddress(String address)

    {

       this.address = address;

    }

    @Override

    public int hashCode()

    {

       final int prime = 31;

       int result = 1;

       result = prime * result + ((address == null) ? 0 : address.hashCode());

       result = prime * result + age;

       result = prime * result + ((name == null) ? 0 : name.hashCode());

       return result;

    }

    @Override

    public boolean equals(Object obj)

    {

       if (this == obj)

           return true;

        if (obj == null)

           return false;

       if (getClass() != obj.getClass())

           return false;

       Person other = (Person) obj;

       if (address == null)

       {

           if (other.address != null)

              return false;

       }

       else if (!address.equals(other.address))

           return false;

       if (age != other.age)

           return false;

       if (name == null)

       {

           if (other.name != null)

              return false;

       }

       else if (!name.equals(other.name))

           return false;

       return true;

    }

    @Override

    public String toString()

    {

       return name + ", " + age + ", " + address;

    }

}

 

 

限制泛型的可用类型

在定义泛型类别时,预设可以使用任何的类型来实例泛型类型中的类型。

但是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口。

public class ListGeneric<T extends List>

{

    private T[] objArr;

   

    public T[] getObjArr()

    {

       return objArr;

    }

 

    public void setObjArr(T[] objArr)

    {

       this.objArr = objArr;

    }

 

    public static void main(String[] args)

    {

       ListGeneric<ArrayList> listGeneric1 = new ListGeneric<ArrayList>();

       ListGeneric<LinkedList> listGeneric2 = new ListGeneric<LinkedList>();

      

       ArrayList[] arrList = new ArrayList[3];

       listGeneric1.setObjArr(arrList);

      

       LinkedList[] linkList = new LinkedList[3];

       listGeneric2.setObjArr(linkList);

    }

}

 

 

当没有指定泛型继承的类型或接口时,默认使用T extends Object ,所在默认情况下任何类型都可以作为参数传入。

 

如果想要在使用时对泛型类型进行约束,可以使用通配说明<? extends List>

 

public class GenericTest7s

{

    public static void main(String[] args)

    {

       //GenericTest的泛型参数类型限定为指定的类 或接口

       GenericTest<? extends List> list = null;

      

       list = new GenericTest<ArrayList>();

      

       list = new GenericTest<LinkedList>();

      

       //GenericTest的泛型参数类型限定为List的基类。

       GenericTest<? super List> list2= null;

       list2 = new GenericTest<Object>();

      

       GenericTest<String> list3 = new GenericTest<String>();

      

       list3.setList("Hello");

      

       //GenericTest<?>相当于GenericTest<? extends Object>

       GenericTest<?> list4 = list3;

      

       System.out.println(list4.getList());

      

       //这行会报错,因为list4的参数类型是Object类型的,用其他类型时要强制类型转换。

       //违背了使用泛型的初衷。

       //list4.setList("World");

    }

}

 

class GenericTest<T>

{

    private T list;

 

    public T getList()

    {

       return list;

    }

 

    public void setList(T list)

    {

       this.list = list;

    }

}

 

 

 

使用<?>或是<? extends SomeClass>的声明方式,意味着你只能通过该名称来取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不能确定是什么类型的实例,编译器不让你加入信息,理由是,如果可以加入信息的话,那么你就得记得取回的实例是什么类型的,然后再去转换为原来的类型方可进行操作,这样就失去了泛型的意义 。

public class GenericTest

{

    public static void main(String[] args)

    {

       Foo<? extends Object> f3 = new Foo<String>();

       f3.setFoo(null);

       //编译器会报错,因为你可以插入成功的话,那么取出来时就要进行强制类型转换,这样做就失去了泛型的意义。

       f3.setFoo("hello");

    }

}

 

class Foo<T>

{

    private T foo;

 

    public T getFoo()

    {

       return foo;

    }

 

    public void setFoo(T foo)

    {

       this.foo = foo;

    }

}

 

 

 

<? super List> 表示泛型类型是List的基类,一般很少用。

 

List<? extends Object > 通常简写为List<?>

 

 

泛型的继承

class Parent<T, K>

{

    private T foo1;

    private K foo2;

 

    public T getFoo1()

    {

       return foo1;

    }

 

    public void setFoo1(T foo1)

    {

       this.foo1 = foo1;

    }

 

    public K getFoo2()

    {

       return foo2;

    }

 

    public void setFoo2(K foo2)

    {

       this.foo2 = foo2;

    }

}

 

class Child<T, K, V> extends Parent<T, K>

{

    private V foo3;

 

    public V getFoo3()

    {

       return foo3;

    }

 

    public void setFoo3(V foo3)

    {

       this.foo3 = foo3;

    }

}

 

 

实现泛型的接口

interface Father<K,V>

{

    public void setKey(K key);

    public void setValue(V value);

}

 

class SubClass<K,V> implements Father<K,V>

{

    private K key;

    private V value;

   

    @Override

    public void setKey(K key)

    {

       this.key = key;

    }

 

    @Override

    public void setValue(V value)

    {

       this.value = value;

    }

}

 

 

增强for循环

 

public class ForTest

{

    public static void main(String[] args)

    {

       int[] arr = {1,2,3,4,5,6};

       for(int i : arr)

       {

           System.out.println(i);

       }

      

       System.out.println("----------------------");

      

       ArrayList<String> list = new ArrayList<String>();

      

       list.add("aaa");

       list.add("bbb");

       list.add("ccc");

      

       for(String str : list)

       {

           System.out.println(str);

       }

      

       System.out.println("----------------------");

      

       int[][] arr2 = {{1,2,3},{4,5,6},{7,8,9}};

      

       for(int[] a : arr2)

       {

           for(int i : a)

           {

              System.out.println(i);

           }

       }

    }

}

 

 

统计命令行中单词出现的次数

public class Frequency

{

    public static void main(String[] args)

    {

       Map<String,Integer> map = new HashMap<String,Integer>();

      

       for(String word : args)

       {

           Integer times = map.get(word);

           map.put( word, (null == times) ? 1 : (times + 1));

       }

      

       System.out.println(map);

    }

}

 

 

 

 

自动装箱和拆箱

自动装箱:基本类型自动转为包装类:int --> Integer

自动拆箱:包装类自动转为基本类型:Integer --> int

public class AutoBoxingAndUnboxing

{

    public static void main(String[] args)

    {

       int i = 3;

       ArrayList<Integer> list = new ArrayList<Integer>();

      

       list.add(i);

       list.add(i+3);

      

       for(int ele : list)

       {

           System.out.println(ele);

       }

    }

}

 

public class AutoBoxingTest

{

    public static void main(String[] args)

    {

       Map<String,Integer> map = new HashMap<String,Integer>();

      

       for(String str : args)

       {

           if(map.containsKey(str))

           {

              int val = map.get(str);

              map.put(str,(val+1));

           }

           else

           {

              map.put(str,1);

           }

       }

      

       Set<Map.Entry<String,Integer>> set = map.entrySet();

       for(Map.Entry<String,Integer> entry : set)

       {

           String key = entry.getKey();

           int val = entry.getValue();

          

           System.out.println(key + ":" + val);

       }

    }

}

 

 

Integer类有一个缓存,它会缓存介于-128127之间的整数 

public class IntCache

{

    public static void main(String[] args)

    {

       Integer a = 100;

       Integer b = 100;

      

       System.out.println(a == b);//true

      

       a = 200;

       b = 200;

      

       System.out.println(a == b);//false

    }

}

 

 

可变参数

可变参数使程序员可以声明一个接受可变数目参数的方法。

注意:可变参数必须是方法声明中的最后一个参数。

public class TestVarArgs

{

    //当有多个参数时, int... args必须是参数表中的最后一个

    static void sum(int... args)

    {

       int sum = 0;

       for(int i : args)

       {

           sum += i;

       }

      

       System.out.println(sum);

    }

   

    public static void main(String[] args)

    {

       //相当于C#中的params int[].

       sum(1,2);

       sum(1,2,3,4,5);

       sum(new int[]{1,2,3});

    }

}

 

 

枚举

 

枚举在某种层次上相当于类,和类或接口处于同一级别之上,通常只是用枚举来定义一些常量。

public enum Color

{

    Red,

    Blue,

    Green

}

 

public class ColorTest

{

    public static void main(String[] args)

    {

       Color color = Color.Red;

      

       System.out.println(color);

      

       System.out.println();

      

       for(Color col : Color.values())

       {

           System.out.println(col);

       }

    }

}

 

 

public class EnumTest

{

    public static void doOperator(OpConst opConst)

    {

       switch(opConst)

       {

           case TURN_LEFT:

              System.out.println("向左转");

              break;

           case TURN_RIGHT:

              System.out.println("向右转");

              break;

           case SHOOT:

              System.out.println("射击");

              break;

       }

    }

   

    public static void main(String[] args)

    {

       doOperator(OpConst.TURN_LEFT);

       doOperator(OpConst.TURN_RIGHT);

       doOperator(OpConst.SHOOT);

    }

}

 

enum OpConst

{

    TURN_LEFT,

    TURN_RIGHT,

    SHOOT

}

 

 

定义枚举类型时,本质上就是在定义一个类别,只不过很多细节由编译器帮你完成了,所以某种程序上,enum关键字的作用就是classinterface.

public enum Coin

{

  //枚举的实例,默认都是public static final

    Penny("Hello"),Dime("World"),Chome("welcome");

   

  //枚举的属性

    private String value;

   

    //枚举的方法,可以被每个实例成员调用

    public String getValue()

    {

       return this.value;

    }

   

  //枚举的构造函数

    private Coin(String value)

    {

       this.value = value;

    }

   

    public static void main(String[] args)

    {

       Coin coin = Coin.Chome;

       System.out.println(coin.getValue());

    }

}

 

 

 

 

我们所定义的每个枚举类型都继承自java.lang.Enum类,枚举中的每个成员默认都是public static final的。

 

每个枚举的成员其实就是你定义的枚举类型的实例。

 

 

EnumSet集合的使用

public class EnumTest4

{

    public static void main(String[] args)

    {

    //把指定的枚举实例添加到集合中

       EnumSet<FontConst> enumSet = EnumSet.of(FontConst.Normal, FontConst.Bold);

       showEnumTest(enumSet);

       System.out.println("-----------------");

      

    // complementOf方法,用于获得指定集合中不包含的成员

       showEnumTest(EnumSet.complementOf(enumSet));

       System.out.println("-----------------");

      

    // noneOf表示用FontConst类型创建一个空的集合

       enumSet = EnumSet.noneOf(FontConst.class);

       enumSet.add(FontConst.Normal);

       enumSet.add(FontConst.Bold);

      

       showEnumTest(enumSet);

    }

   

    public static void showEnumTest(EnumSet<FontConst> enumSet)

    {

       for(Iterator<FontConst> iter = enumSet.iterator(); iter.hasNext();)

       {

           System.out.println(iter.next());

       }

    }

}

 

enum FontConst

{

    Normal,Bold,Italilc

}

 

 

 

枚举集合的拷贝

public class EnumSetTest

{

    public static void main(String[] args)

    {

       ArrayList<FontConst> list = new ArrayList<FontConst>();

      

       list.add(FontConst.Normal);

       list.add(FontConst.Bold);

       list.add(FontConst.Italilc);

      

       //把指定的列表集合拷贝到枚举集合中去

       showEnumTest(EnumSet.copyOf(list));

    }

   

    public static void showEnumTest(EnumSet<FontConst> enumSet)

    {

       for(Iterator<FontConst> iter = enumSet.iterator(); iter.hasNext();)

       {

           System.out.println(iter.next());

       }

    }

}

 

 

EnumMap的使用

public class EnumMapTest

{

    public static void main(String[] args)

    {

       Map<Action,String> map = new EnumMap<Action,String>(Action.class);

      

       map.put(Action.TURN_RIGHT,"向右转");

       map.put(Action.SHOOT,"射击");

       map.put(Action.TURN_LEFT,"向左转");

      

       Set<Action> set = map.keySet();

       for(Action key : set)

       {

           System.out.println(map.get(key));

       }

    }

}

 

enum Action

{

    TURN_LEFT,TURN_RIGHT,SHOOT;

}

 

 

一个使用枚举较为合适的场景

public class AccessControl

{

    public static void main(String[] args)

    {

       AccessRight right = AccessRight.valueOf("MANAGE");

      

       System.out.println(checkRight(right));

    }

   

    public static Boolean checkRight(AccessRight right)

    {

       if(right == AccessRight.MANAGE)

       {

           return true;

       }

       return false;

    }

}

 

enum AccessRight

{

    MANAGE,DEPARTMENT,EMPLOYEE;

}

 

 

静态导入

在另一个包中如下这个类

package com.anllin.common;

 

public class Common

{

    public static final int AGE = 10;

   

    public static void output()

    {

       System.out.println(AGE);

    }

}

在当前包中,静态导入后可以象使用内部类成员一样访问common类的AGE常量。

虽然在一定程度上带来了便利,但会降低程序的可读性。

package com.anllin.jdk5;

 

import static com.anllin.common.Common.AGE;

import static com.anllin.common.Common.output;

 

public class StaticImportTest

{

       public static void main(String[] args)

       {

              int age = AGE;

              output();

       }

}

 

 

 

posted @ 2011-08-17 22:46  水之原  阅读(266)  评论(0编辑  收藏  举报