Java泛型集合的理解

简介:

 什么是泛型?

泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象。

因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为期望的类型,如下面的代码所示:

 
  1. Map m = new HashMap(); 
  2. m.put("key""value"); 
  3. String result = (String)m.get("key"); 

 

想让程序编译通过,必须将m.get(“key”)强制转换为String类型,因为这里放入了String类型的值,取得的结果也一定是String类型的。如果你往map里放入了不是String类型的值,那么将会报ClassCastException错误。

理想情况下,您可能会得出这样一个观点,即 m 是一个 Map,它将 String 键映射到 String 值。这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。

泛型带来的好处

类型安全

限制了变量定义的类型。

消除强制类型转换

还是拿刚才的例子说

 
  1. Map<String, String> m = new HashMap<String, String>(); 
  2. m.put("key""value"); 
  3. String result = m.get("key"); 

 

 

上面的代码是不是少了强制转换而且代码看着也简洁多了,这就是泛型的好处之一。平时大家写的时候,编辑器会有个黄色的感叹号来提醒你需要使用泛型。

泛型的通配符

?通配符

使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

下面看个例子:

 
  1. public class People { 
  2.  
  3.     private String name; 
  4.     private String job; 
  5.  
  6.     public People() { 
  7.     } 
  8.  
  9.     public People(String _name, String _job, int _sex) { 
  10.         this.name = _name; 
  11.         this.job = _job; 
  12.         this.sex = _sex; 
  13.     } 
  14.  
  15.     public void SayHello() { 
  16.         System.out.println("我是一位" + job + ";我的名字叫" + name); 
  17.     } 
  18.  
  19.     public String getName() { 
  20.         return name; 
  21.     } 
  22.  
  23.     public void setName(String name) { 
  24.         this.name = name; 
  25.     } 
  26.  
  27.     public String getJob() { 
  28.         return job; 
  29.     } 
  30.  
  31.     public void setJob(String job) { 
  32.         this.job = job; 
  33.     } 
  34.  
  35.     public int getSex() { 
  36.         return sex; 
  37.     } 
  38.  
  39.     public void setSex(int sex) { 
  40.         this.sex = sex; 
  41.     } 
  42.  
  43.     private int sex; 
  44.  

 

 
  1. public class SoftwareEngineer extends People{ 
  2.      
  3.     public void coding(){ 
  4.         System.out.println("coding……"); 
  5.     } 

 

 
  1. public class Cook extends People { 
  2.  
  3.     public void cook(){ 
  4.         System.out.println("cooking……"); 
  5.     } 

主方法:

 
  1. List<? super People> flist = new ArrayList<People>(); 
  2.         flist.add(new People());
  3.         SoftwareEngineer soft = (SoftwareEngineer) flist.get(0); 
  4.         soft.coding(); 

输出结果:coding……

注意这里是super,那么flist.add()里面添加new People(),也可以添加new SoftwareEngineer()或者new Cook(),都可以!

那么,我们换成下面的看看:

 
  1. List<? extends People> flist = new ArrayList<People>(); 

这里就不可以添加了。。。?

list中为什么不能加入people类和people类的子类呢,原因是这样的:  

List<? extends People>表示上限是People,下面这样的赋值都是合法的  

 
  1. List<? extends People> list1 = new ArrayList<People>();   
  2. List<? extends People> list2 = new ArrayList<SoftWareEngineer>();   
  3. List<? extends People> list3 = new ArrayList<Cook>();  

如果List<? extends People>支持add方法的方法合法的话:

   list1可以add People和所有People的子类  

   list2可以add SoftWareEngineer和所有SoftWareEngineer的子类  

   list3可以add Cook和所有Cook的子类  

这样的话,问题就出现了  

   List<? extends People>所应该持有的对象是People的子类,而且具体是哪一个子类还是个未知数,所以加入任何People的子类都会有问题,因为如果add People的话,可能List<? extends People>持有的对象是new ArrayList<Cook>() SoftWareEngineer的加入肯定是不行的,如果 如果add Cook的话,可能List<? extends People>持有的对象是new ArrayList<Cook的子类>()  

   SoftWareEngineer的加入又不合法,所以List<? extends People> list 不能进行add,而List<? super People> list 表示list持有的对象是People的父类,下限是 People,所以list中add People或People的子类是没有问题的。



本文转自shyy8712872 51CTO博客,原文链接:http://blog.51cto.com/shuyangyang/1030760,如需转载请自行联系原作者


相关文章
|
3月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
246 100
|
3月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
279 101
|
3月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
2月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
91 7
|
3月前
|
安全 Java
Java之泛型使用教程
Java之泛型使用教程
244 10
|
4月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
264 23
|
3月前
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
|
4月前
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
4月前
|
安全 Java 开发者
Java集合框架:详解Deque接口的栈操作方法全集
理解和掌握这些方法对于实现像浏览器后退功能这样的栈操作来说至关重要,它们能够帮助开发者编写既高效又稳定的应用程序。此外,在多线程环境中想保证线程安全,可以考虑使用ConcurrentLinkedDeque,它是Deque的线程安全版本,尽管它并未直接实现栈操作的方法,但是Deque的接口方法可以相对应地使用。
245 12
|
4月前
|
存储 NoSQL Java
Java Stream API:集合操作与并行处理
Stream API 是 Java 8 提供的集合处理工具,通过声明式编程简化数据操作。它支持链式调用、延迟执行和并行处理,能够高效实现过滤、转换、聚合等操作,提升代码可读性和性能。