Java集合框架-------泛型

简介: Java集合框架-------泛型

JAVA自动装箱和自动拆箱:

装箱:将一个值封装称为一个对象的过程

举例:

Integer number=new Integer(100);

拆箱:从一个类型包装器中提取值的过程

举例:

int i=number.intValue();

装箱和拆箱是Java最初的版本中就存在的,他并不是Java1.5的新特性,自动拆装箱,当编译器编译时若发现是基本类型与包装类型之间相互赋值,将自动补充代码来完成转换工作,这个过程称为自动拆装箱。

自动拆箱和装箱:

自动装箱:当我们需要某个类型的对象时,该基本类型的数据类型自动被封装到与它相同类型的包装器中

举例:

Integer number=100;//直接将基本数据类型的值赋值给类包装器

自动拆箱与自动装箱相反,当我们需要一个值时,这个被装箱到对象中的值就会被自动的提取出来,不需要我们手动的去调用xxxvalue()方法。

举例:

int i=number;//直接将这个对象引用赋值给一个基本的变量即可

那么为什么要自动装箱和自动拆箱操作呢?


原因是可以大大简化基本类型变量和包装类对象之间的转换过程。


包装类:


通常情况下基本的数据类型,它只是一个类型而不是一个对象,JAVA是一个面向对象的编程语言,那么就需要将基本类型打包封装成对象,而将这些基本类型进行对象化的相关类就是包装类。


java定义了8个包装类,包括:Integer、Character、Byte、Short、Long、Float、Double、Boolean,其中Character和Boolean是直接继承自Object的,而其余6个包装类继承自java.lang.Number类。


即为了解决基本类型不能直接参与面向对象开发的问题,使得基本类型可以通过包装类的形式存在。## 泛型:

泛型是JDK5.0的新特征,泛型的本质是参数化类型,即程序中所操作的数据类型被指定为一个参数。


Java语言引入泛型的好处是安全简单,可以避免强制类型转换而产生的ClassCastException,在JDK5.0之前,在没有泛型的情况下,通过对类型Object的引用来实现参数的“任意化”。


泛型可以用在类,接口和方法的创建中,分别称为泛型类,泛型接口,泛型方法。


泛型头部定义格式如下:

[修饰符] class 类名<T>
[public] interface 接口名<T>
[public][static]<T> 返回值类型 方法名(T参数)

泛型类的定义和创建:

一般情况下,我们使用K,T,E,V等字母表示泛型类型参数,泛型类在命名上仍然要符合标识符的命名规则。

[public] class 泛型类名<形式类型参数1,形式类型参数1>
//形式类型参数列表用于指明当前泛型可接受的类型参数占位符的个数,参数是任意的,不同参数之间我们使用逗号隔开
{
类体
}

注:泛型的类型参数只能是引用数据类型,不能是基本数据类型


普通类在创建对象的过程中,都是直接进行创建的,但是泛型类在创建对象时,需要使用实际的参数类型去代替泛型类中的参数类型


举例:

person <String> name=new person<String>();//这里的String即为实际参数类型

泛型类的简单使用:

package generics;
public class generics<T> {
    private  T obj;
    public generics(T obj) {
        this.obj = obj;
    }
    public T getObj() {
        return obj;
    }
    public void setObj(T obj) {
        this.obj = obj;
    }
    public void showObj(){
        System.out.println("T的实际类型为:"+obj.getClass().getName());
    }
}
package generics;
public class generics1 {
    public static void main(String[]args){
    //定义泛型类generics的一个Integer类型
        generics<Integer> number=new generics<Integer>(67);
        number.showObj();
        int number1=number.getObj();
        System.out.println("数字为:"+number1);
        //定义泛型类generics的一个String类型
        generics<String> str=new generics<String>("hello,java");
        str.showObj();
        String str1=str.getObj();
        System.out.println("字符串为:"+str1);
    }
}

输出:

T的实际类型为:java.lang.Integer
数字为:67
T的实际类型为:java.lang.String
字符串为:hello,java

泛型接口:

定义如下:

[public] interface 接口名<T>
{
抽象方法
}

泛型接口的实现必须通过泛型类

泛型接口的简单使用:

package generics;
public class generics<T> implements text1<T>{//通过泛型类去实现泛型接口
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}
package generics;
public interface text1<T> {
    void show(T t);
}
package generics;
public class generics1 {
    public static void main(String[]args){
       generics<String> inter1=new generics<String>();//传递String类型
       inter1.show("我爱中国");
       generics<Double> inter2=new generics<Double>();//传递double类型
       inter2.show(99.0);
    }
}

输出:

我爱中国
99.0

泛型的优点:

泛型对程序带来的主要优点有两部分:

1:类型安全,泛型的主要目标是提高Java程序的类型安全。

2:消除强制转换类型,采用了泛型后,所有强制转换类型都是自动地和隐式的,这样就提高了代码的重用率。

package generics;
public class generics1 {
  private Object obj;
  public generics1(Object obj){
      this.obj=obj;
  }
  public Object getObj(){
      return obj;
  }
  public void showType(){
      System.out.println("实际类型是:"+obj.getClass().getName());
      //getClass()会获得对象执行时的Class实例,调用getName() 可以获取类的名称
  }
}

不强制转化:

generics1 grade=new generics1(90.3);
grade.showType();
double i=grade.getObj();
System.out.println("成绩="+i);

报错:

不使用泛型的情况下,必须进行强制类型转换!

package generics;
public class generics{
   public static void main(String[]args){
        generics1 grade=new generics1(90.3);
       grade.showType();
       double i=(double)grade.getObj();
       System.out.println("成绩="+i);
       generics1 name= new generics1("张三");
       name.showType();
       String name1=(String)name.getObj();
       System.out.println("名字是"+name1);
       generics1 number=new generics1(100);
       number.showType();
       int number1=(int)number.getObj();
       System.out.println("数字是"+number1);
       generics1 height=new generics1(180.2f);
       height.showType();
       Float weight1=(Float)height.getObj();
       System.out.println("身高是"+weight1);
   }
}

输出:

实际类型是:java.lang.Float
成绩=90.3
实际类型是:java.lang.String
名字是张三
实际类型是:java.lang.Integer
数字是100
实际类型是:java.lang.Float
身高是180.2

提醒:float的f是必须要加的,不加就编译出错!


float类型末尾加f(必须加) :


例如 float f = 90.3f

90.3是浮点数,默认是double类型,如果不加f去标记的话,那这个浮点数就是从double类型转换成了float类型,属于向下转型,必须得加小括号进行强制转换

通用符与受限的泛型类型:

泛型的类型通配符是"?“,使用”?"作为类型参数,代表任何可能的类型。

例如: Set<?>

它表示Set集合中可以存放任意一种类型的对象,泛型Set<?>是任何泛型Set的父类,Set<?>类型的变量在调用方法时是受到限制的;凡是必须知道具体类型参数的操作都不能执行。

package generics;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.Vector;
public class generics{
   public static void main(String[]args){
       Set<String> set=new HashSet<String>();
       set.add("王俊凯");
       set.add("王源");
       set.add("易烊千玺");
   }
   public static void showELement(Set<?> v){
       v.add(new Date());//尝试创建具体参数类型!报错
       for(int i=0;i<v.size();i++){
           Object obj=v.elementAt(i);
           System.out.println(obj);
       }
       v.clear();
   }
}

报错:

原因为:形参v是通配符类型的Set对象,此处明确要添加的类型为Date,所以编译器阻止该操作,上文我们说到凡是必须知道具体类型参数的操作都不能执行。


在定义泛型类时,默认可以使用任何类型来实例化一个泛型类的对象,但也可以在用泛型类创建对象时对数据做出限制。

举例:

class ClassName<T extends anyClass>

其中anyClass是某个类或者接口,他表示泛型类型只能是anyClass的子类或者子接口,使用通配符"?"创建泛型类对象,通配符的主要作用是在创建一个泛型类对象时限制这个泛型类的类型是某个或者是继承该类的子类或者是实现某个接口的类.

举例:

ArrayList<? extends Number>

表示泛型类型只能是Number的子类。

受限泛型的简单使用:

package generics;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.Vector;
public class generics<T extends Number>{//该泛型只能是Number的子类或者子接口
   private T obj;
   public generics(T obj){
       this.obj=obj;
   }
   public T getObj(){
       return obj;
   }
}
package generics;
public class generics1 {
public static void main(String[]args){
    generics<Integer> num1=new generics<Integer>(5);
    System.out.println("给出的参数是"+num1.getObj());
    generics<Double> num2=new generics<Double>(8.8);
    System.out.println("给出的参数是"+num2.getObj());
}
}

输出:

给出的参数是5
给出的参数是8.8

但如果参数传递的类型为如下所示的String类型,编译则不通过,原因为String并不是Number的子类。

generics<String> s=generics<String>("hello");

泛型的局限性:

1:泛型的参数不能被实例化
2:不能声明参数化类型的数组
3:不能用基本类型替换引用类型参数
4:不能定义带泛型的异常,不允许定义Throwable的泛型子类
5:不能在静态变量或者静态方法中引用类中声明的类型参数

Java泛型的主要作用是建立在具有类型安全的数据结构,它在集合框架中的应用非常广泛

相关文章
|
28天前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
28天前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
1月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
135 3
|
10天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
32 5
|
23天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
34 4
|
1月前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
45 2
|
1月前
|
前端开发 Java 数据库连接
你不可不知道的JAVA EE 框架有哪些?
本文介绍了框架的基本概念及其在编程领域的应用,强调了软件框架作为通用、可复用的软件环境的重要性。文章分析了早期Java EE开发中使用JSP+Servlet技术的弊端,包括可维护性差和代码重用性低等问题,并阐述了使用框架的优势,如提高开发效率、增强代码规范性和可维护性及提升软件性能。最后,文中详细描述了几种主流的Java EE框架,包括Spring、Spring MVC、MyBatis、Hibernate和Struts 2,这些框架通过提供强大的功能和支持,显著提升了Java EE应用的开发效率和稳定性。
63 1
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
47 0
|
4月前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。