黑马程序员_集合、可变参数、泛型

本文深入讲解了Java中的增强for循环、可变参数、枚举、自动拆箱与装箱及泛型等高级特性,帮助读者更好地理解和应用这些特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    主要介绍增强for循环、集合、枚举以及泛型

 增强for循环:

 foreach语句:foreach简化了迭代器

格式://for(Object obj :Collection集合 & 数组)迭代出arg里面的元素

高级for循环和传统for循环的区别:

高级for循环在使用的时候不用指定要循环的次数,必须要有被迭代的目标,这个目标,可以是Collection和数组,但是Collection集合的时候,在遍历过程中不可以对集合中的元素进行操作。比如删除动作。如果遍历数组,还需要对数组元素进行操作,建议使用传统for循环因为可以使用数组的下标对数组进行相对应的操作。如果只是想获得集合或者数组里面的所有元素,则建议使用高级for循环。

增强for循环可以迭代集合,但是却不能迭代Map集合,想要迭代Map集合,必须要将Map集合转换为Collection集合。因为增强for循环只能针对实现了Iterator接口的集合进行迭代:iterator是jdk1.5中新定义的接口,就是一个方法iterator方法,只有实现了Iterator接口的类,才能保证一定有iterator方法,java有这样的限定是因为增强for循环内部还是用迭代器实现的,而实际上,我们可以通过某种方式来使用增强for循环。

for(Object obj : map.entrySet){
                 Map.Entry   map = (Entry)obj;
                sop(map.getKey()+":"+map.getValue());


}

使用迭代器注意的有:在使用Iterator迭代集合中的元素的时候,不可以对集合中的元素进行删除和增加操作,这样以来就会报错。可以用迭代器的Iterator的子接口listIterator接口,这个接口就可以对集合进行增删等的操作。


可变参数(Object... obj):

我们学习过函数重载的形式,如果要调用多个参数的函数时,比如说一下调用两个参数的函数,一下有调用四个参数的同一个方法,这是要用到函数重载的,这样调用同一方法,只要参数不一样,就得重载这个方法。这样一来就可能会产生很大的构造函数。使用泛型,当要操作的同一个类型元素个数不确定的时候,可以使用泛型这个方式,这个参数可以接受任意个数的同一类型的数据。

和接受数组不一样的是:

以前定义数组类型,需要先创建一个数组对象,再将这个数组对象作为参数传递给函数。现在,直接将数组中的元素作为参数传递即可。底层其实是将这些元素进行数组的封装,而这个封装动作,是在底层完成的,被隐藏了。所以简化了用户的书写,少了调用者定义数组的动作。

      如果在参数列表中使用了可变参数,可变参数必须定义在参数列表结尾(也就是必须是最后一个参数,否则编译会失败)比如说

public  void show(int num, int... num1);正确

public void show(int... num1,int num);错误

如果要获取多个int数的总和呢?可以使用将多个int数封装到数组中,直接对数组求和即可,也就是说直接传递数组,可变参数同样也可以接受数组。


枚举:关键字 enum

问题:对象的某个属性的值不能使任意的,必须为固定的一组取值其中的某一个:jdk5中新定义了枚举类型,专门用于解决此类问题,枚举就是一个特殊的java类,可以定义属性、方法、构造函数、实现接口、继承类;


自动拆箱与装箱

java中数据类型分为两种类型:基本数据类型和引用数据类型;

在java程序中所有的数据都需要当中对象来处理,针对8中基本数据类型提供了包装类,如下:

int ->Integer

byte->Byte

short->Short

long->Long

char->Character

float->Float

double->Double

boolean ->Boolean

jdk5 以前基本数据类型和包装类之间需要互相装换,基本<--------->引用 Integer x = new Integer(int i); int num = i.intValue();

(1)、Integer x = 1; x = x+1;经历的了装箱、拆箱、装箱;

(2)、为了优化,虚拟机为包装类提供了缓冲池,Integer池的大小为 -128-127一个字节地大小。也就是说在这个范围内的整数都会被在这个缓冲池中,他们的内存地址都是一样的。

(3)、String池 :java为了优化字符串操作  提供了一个缓冲区;


泛型:<>

①将运行时期的问题ClassCastException(类型转换异常)问题转换成为了编译失败,体现在编译时期,程序员就可以解决问题。

②在使用泛型的时候,只有带有<>的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给<>中传递一个具体的引用数据类型。

③泛型擦除:泛型的只是在编译时期供编译器具体的类型,到运行时期,泛型的限制就会消失。

④泛型补偿:存储的时候,类型确定,所以在取出元素的时候不用进行强转,内部机制会帮你完成这一操作,以前是当操作的数据类型不确定的时候,我们使用的Object来接收一个对象,再进行强转,有了泛型后,可以指定需要什么样类型的参数,取出时就可以直接指定取出的是什么类型


泛型定义有几种类型:①定义方法上

 

public<T> void show(T t){

        sop("show"+t);

}
静态方法上的泛型:静态方法无法访问类上定义的泛型,如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上,定义前一定要进行泛型的声明。

                          ②定义在类上

public class Demo<T t>{

         该类中可以直接使用T进行变量的定义
}


泛型中的通配符:可以解决具体类型不确定的时候,是用”?“通配符,也就是说他可以接收任意类型的对象,接收到什么样类型的对象,?就代表是那一个类型。也就相当于是Object,不需要使用类型的具体的功能时,使用的是Object类中的功能,那么可以用?通配符来表示位置类型。

泛型限定:

上限:? extends  E:<>内能接收E以及E的子类对象

下限:? super E:<>内可以接收E或者E类型的父类

需要使用上限时期:向集合中添加元素的时候,规定加入的元素只能是E或者E的子类对象,这样取出元素的时候,直接使用E接收就可以了

下限使用:当从集合中获取元素进行操作的时候,可以用当前元素进行接收,也可以用当前元素的父类型接收。


泛型小知识点:

①泛型属于什么类型鉴于调用者传入的是什么类型,没有传入类型,默认的是Object类型

②使用带泛型的类创建对象时,等式两边的泛型类型必须一致:

③等式两边可以再任意一边使用泛型,在另一边不使用,

ArrayList<String> arr = new ArrayList<Object>();//错

ArrayList<Object> arr = new ArrayList<Stirng>();//错

在使用泛型的时候还是尽量保证两边的泛型类型相同,以至于不轻易发生错误





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值