您的位置:首页 > 其它

第二十七条:优先使用泛型方法

2016-09-05 10:27 253 查看

一、泛型方法的优点(一)

优点:泛型方法能够推断出输入参数中的参数类型
例:
public <E> E getType(E type){
return type;
}
//当使用该方法的时候,虚拟机能够推断出输入的参数的类型是什么,并返回该类型。
举例:合并两个Set列表,用原生类型方法与泛型方法比较
//原生类型方法
public Set union(Set set1,Set set2){
Set set = mew HashSet(s1);
set.addAll(set2);
return set;
}
使用原生类型方法虚拟机会出现类型不安全的警告。
//泛型方法
public <E> Set<E> union(Set<E> set1,Set<E> set2){
Set<E> set = new HashSet<E>(set1);
set.addAll(set2);
return set;
}
//由于虚拟机能够推断出输入参数的参数类型,所以E是已知的,不会出现类型不安全的警告。
使用:
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> firstSet = new HashSet<String>(
Arrays.asList("Bady","Tim","Alice"));
Set<String> secondSet = new HashSet<String>(
Arrays.asList("Come","On","Go","With","Me"));
Set<String> set = union(firstSet, secondSet);
System.out.println(set);
}

二、泛型的优点(二)

优点:能够推断出被赋值对象的类型参数。
例:泛型的静态工厂方法
public static void main(String[]args){
HashMap<String, String> map = newHashMap();
}
//泛型方法
public static <K,V> HashMap<K,V> newHashMap(){
return new HashMap<K, V>();
}
这就是虚拟机能够根据被赋值对象的类型参数,推断出K,V的值是String,String。这样K,V就是已知类型。
我们以前写含有泛型的容器的时候都是:
HashMap<String,String> hashMap = new HashMap<String,String>();
在new 的时候还需要再重写一遍类型参数。一个两个还好,当数量多的时候呢。
所以利用泛型的静态工厂是一种方便的方法。

三、泛型的优点(三)

优点:能够推断出被赋值对象的类型。
是不是跟优点(二)有点像。不过这个是能够推断被赋值对象的类型,优点二则是推断被赋值对象的类型参数,不要弄混了。
例:
在Android中声明layout中的View到代码中的时候,都要使用(View)findViewById(R.id.xxx);
就像这样:Button btn = (Button)findViewById(R.id.xxx);每次有需要强制转换是一种很繁琐的事情。
我们可以这样构建一个方法
public void onCreate(Bundle bundle) {
// TODO Auto-generated method stub
Button btn = getViewById(R.id.xxx);
}
//泛型方法
<span style="white-space:pre">	@SuppressWarnings("unchecked")</span>
public <VT> VT getViewById(int id){
return (VT)findViewById(id);
}
因为虚拟机能够推断出被赋值对象的类型,也就是能够推断出VT为Button类型。这样VT就是确定的类型,就不会出现类型不安全的问题。这样就能放心的消除警告了

注:优点(二)(三)方法使用的基础,都是基于赋值给被赋值对象。如果没有被赋值对象,直接调用方法会发生什么情况呢?
就像这样:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setView(getViewById(R.id.main_tv));//报错
}

//所有Button,等控件都是View的子类。
//作用:将生成的View放入该方法中
public void setView(View view){
View myView = view;
}

public <VT> VT getViewById(int id){
return (VT)findViewById(id);
}
如果没有被赋值对象,虚拟机就无法进行判断,返回的类型就是Object,就是说getViewById()返回的是Object。
因为Object != View 所以肯定会出错

四、有限制的类型参数的特殊形式(递归的类型限制)
形式:<E extends Comparable<E>>
表述:可以与自身比较的E类
使用情形:一般用于Comparable类
例:求List容器中的最大值
public <T extends Comparable<T>> T calculateMax(List<T> list){
Iterator<T> iterator = list.iterator();
T result = iterator.next();
while (iterator.hasNext()){
T t = iterator.next();
//需要判断大小
if (result.compareTo(t) < 0){
result = t;
}
}
return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: