----------------------
ASP.Net+Unity开发、
.Net培训、期待与您交流! ----------------------
但是通过map可以衍生出另一个知识,就是entry。entry是用来遍历map用的。因为map这个接口本身是没有迭代方法,需要向上转为set,set有iterator方法。entrySet()方法是map转为set的途径,entrySet()会返回装有Map.entry的set。听到这里,也许会有点难以理解,需要记住的就是想要迭代map,找一个方法让它成为set。
在类名旁边定义一个泛型,整个类里就可以应用此泛型。。。在使用对象时可以这样定义。
----------------------
ASP.Net+Unity开发、
.Net培训、期待与您交流! ----------------------
泛型的应用
泛型是Java1.5的新特性,,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。
1.集合中的泛型
class GenericDemo
{
public static void main(String[] args)
{
ArrayList arrayList = new ArrayList() ;
arrayList.add(1) ;
arrayList.add(1l) ; //注意,数字1后面是字母L的小写
int i = (int)arrayList.get(1) ;
}
}
以上代码运行一次会报错
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot b
e cast to java.lang.Integer
at GenericDemo.main(ClassLoadDemo.java:26)
可以看出,整数型转换失败,集合中取出的是长整型,并不是我预期的int。
之所以会出这样的问题,是因为在往集合添加对象时没有一个规范的准则。我们就会希望一个集合我只想让它收集字符串对象。泛型可以帮到我们。
ArrayList<String> al = new ArrayList<String>() ;
按上面这行代码去定义一个集合,在添加元素时你就必须只能添加String类型的对象,想al.add(1) 这么做编译器就会报错,不予通过。这样我们就规定了一个泛型。这一句的泛型命名规则很简单,就把它看作把类名变长了,类名后面追加类型参数,参数用<>包围起来。
如果是有多个数据的哈希类集合,有几个数据就在<>写几个数据对应的类型,中间用“,”英式逗号隔开,如下代码:
HashMap<String,Integer> map = new HashMap<String,Integer>() ;
也是比较容易理解的,这里就不再过多演示。
但是通过map可以衍生出另一个知识,就是entry。entry是用来遍历map用的。因为map这个接口本身是没有迭代方法,需要向上转为set,set有iterator方法。entrySet()方法是map转为set的途径,entrySet()会返回装有Map.entry的set。听到这里,也许会有点难以理解,需要记住的就是想要迭代map,找一个方法让它成为set。
怎么把map变为set呢
class GenericDemo
{
public static void main(String[] args)
{
HashMap<String,Integer> map = new HashMap<String,Integer>() ;
map.put("Tom",22) ;
map.put("Jarry",11) ;
map.put("Join",66) ;
map.entrySet() ;
}
}
首先map.entrySet()得到所有数据包装为entry,再用set对象的entry去接收,因为map有泛型,这个entry也必须保持一样的泛型。所以就得到以下代码:
class GenericDemo
{
public static void main(String[] args)
{
HashMap<String,Integer> map = new HashMap<String,Integer>() ;
map.put("Tom",22) ;
map.put("Jarry",11) ;
map.put("Join",66) ;
Set<Map.entry<String,Integer>> entrySet = map.entrySet() ;
}
}
Map.entry提供了getKey和getValue两个方法读取map里的数据,接下来一个简单的for循环就能把entrySet全部迭代出。代码里不好理解的也就一个嵌套泛型,
Set<Map.entry<String,Integer>> 从外往里看,先规定set只放entry,放什么样的entry呢?再规定是String,Integer的entry。通俗的比喻,一个车只能坐帅哥,帅哥可能是来自美国来自法国来自中国,现在司机只喜欢中国帅哥!
2.方法中的泛型
集合中的泛型最为直观易懂,有了这样的一个入门,再来看有些难度的方法泛型就更加容易理解。方法中的泛型,比较常见的使用方式是通配符。可以在API文档里经常看到Class后面跟有一个泛型标记<>,但是尖括号里面却是一个问号或者一个字母,它代表着可以接受任意类型的参数,这就是通配符。出一个题目,怎样打印任意一个参数化的集合?例如,同一个方法传递这几个collection<Integer>,collection<String>,collection<Object>实参都可以打印。public static void printCollection(Collection<?> collection)
{
for (Object obj : collection)
{
System.out.println(obj) ;
}
}
一个问号就代表这里是未知的,可以理解为属于泛型里的特殊变量,你传过来是什么问号就变为什么,再利用Object打印出来。
注意:因为你不知道collection会是一个什么参数化的集合,所以你也无法执行确定类型的操作,比如add("string")这样添加元素的方法,只能执行无关类型的方法,collection.size()这种可以执行。
有些情况,虽然你希望接收任意参数,但只想要关于数字的不要String,这时可以通过限定上下界来实现。
ArrayList<? extends Number> 上边界,接收Number以及子类
ArrayLIst<? super Integer> 下边界,接收Integer以及父类
如果想要返回值呢
如果想要返回值呢
public static <E> E getSum(E a,E b)
{
return a+b ;
}
方法声明没有写错,但是a+b是错的,还是那个原因,因为是未知的,你不能进行关于类型的操作。改为return null ;就没错了。E只能是引用类型,基本类型是不可以的。int可以自动装箱Integer,但是int[]数组就不会,用这个传给E就会出错。
3.类的泛型
class DAO<E>
{
public void create(E e)
{
//接收任意类型数据
}
public E check(int id)
{
//可以把E返回
}
public Set<e> getCollection(String where)
{
//可以返回集合
}
}</e>
在类名旁边定义一个泛型,整个类里就可以应用此泛型。。。在使用对象时可以这样定义。
DAO<Class> dao = new DAO<Class>()
调用
create
方法时,必须传递
Class
类型数据,调用
check
时返回一个
Class
类型数据必须用
Class
对象接收。
另外,静态方法不能用泛型,泛型只针对new出来的对象实例。
总结
泛型还有很多巧妙的用处,这里没有办法一一全部阐述。有了泛型既可以规范一些内容,也可以不规范内容,可以说为开发带来的方便非常之多。
如有什么特别的使用方法还请不吝赐教!
互相学习互相进步!!