1、增强for循环
增强for循环也成for each循环,是JDK1.5之后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。所有的单列集合都可以使用增强for循环。
格式:
for(集合/数组数据类型 变量名: 集合名/数组名) {
sout(变量名);
}
举例:
public static void demo02() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("aaa");
arrayList.add("bbb");
arrayList.add("ccc");
for (String s:arrayList
) {
System.out.println(s);
}
}
public static void demo01() {
int[] arr = {
1, 2, 3, 4, 5, 6};
for (int i:arr) {
System.out.println(i);
}
}
2、泛型
一种未知的数据类型 当我们不知道使用什么数据类型的时候,可以使用泛型。泛型也可以看成是一个变量,用来接收数据类型。
E e: Element 元素
T t:Type 类型
E:未知的数据类型
public class ArrayList<**E**>{
public boolean add(**E** e) {
}
public **E** get(int index) {
}
}
创建集合对象的时候,就会确定泛型的数据类型。
使用:
public class Demo01Generic {
public static void main(String[] args) {
show02();
}
/*
创建集合对象 使用泛型
好处:
1、避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
2、把运行期异常提升到了编译期
弊端:
泛型是什么类型,就只能存储什么类型的数据了。
*/
private static void show02() {
ArrayList<String> list = new ArrayList<>();
list.add("王雷");
list.add("陈雷");
list.add("黄雷");
list.add("地雷");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s + "->" + s.length());
}
}
/*
创建对象,使用泛型
好处:集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据
弊端:不安全,会引发异常
*/
private static void show01() {
ArrayList list = new ArrayList();
list.add("abc");
list.add(1);
//迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
//想要使用String类特有的方法获取字符串的长度,不能使用。多态 Object obj = "abc";
//需要向下转型
//会抛出异常ClassCastException 不能把Integer转换成String类型
String s = (String) obj;
System.out.println(s.length());
}
}
}
3、泛型的定义和使用
泛型类的定义:
/*
定义一个含有泛型的类,模拟ArrayList集合
泛型是一个未知的数据类型,当我们不确定什么什么数据类型的时候,可以使用泛型
泛型还可以接收任意的数据类型,可以使用Integer,Student,String......
创建对象的时候确定泛型的数据类型
*/
public class GenericClass<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
泛型类的使用:
public class Demo02GenericClass {
public static void main(String[] args) {
//不写泛型默认是Object类型
GenericClass gc = new GenericClass();
gc.setName("只能是字符串");
Object obj = gc.getName();
//创建GenericClass对象,泛型使用Integer
GenericClass<Integer> gc2 = new GenericClass<>();
gc2.setName(1);
int name = gc2.getName();
System.out.println(name);
//泛型使用String
GenericClass<String> gc3 = new GenericClass<>();
gc3.setName("aaacccvvv");
String s = gc3.getName();
System.out.println(s);
}
}
4、定义使用含有泛型的方法
泛型方法类:
/*
定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
格式:
修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)) {
方法体;
}
含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,泛型就是什么类型。
*/
public class GenericMethod {
//定义一个含有泛型的方法
public <M> void method(M m) {
System.out.println(m);
}
//定义含有泛型的静态方法
public static <S> void method02(S s){
System.out.println(s);
}
}
使用类:
/*
测试含有泛型的方法
*/
public class Demo03Generic {
public static void main(String[] args) {
GenericMethod gm = new GenericMethod();
/*
调用含有泛型的方法method
传递什么类型,泛型就是什么类型
*/
gm.method("abc");
gm.method(123);
gm.method(8.8);
gm.method(true);
gm.method02("静态方法不建议创建对象使用");
//静态方法通过类名.方法名可以直接使用
GenericMethod.method02("静态方法");
GenericMethod.method02(12343);
}
}
截图:
5、定义使用含有泛型的接口
接口的定义:
package com.itheima.demo03FanXing;
/*
定义含有泛型的接口
*/
public interface GenericInterface<I> {
public abstract void method(I i);
}
实现类1:
/*
含有泛型的接口,第一种使用方式:定义接口的实现类,
实现接口,指定接口的泛型。
public interface Iterator<E> {
E next();
}
Scanner类实现了Iterator接口,并指定接口的泛型为字符串
所以重写的next方法泛型默认就是String
*/
public class GenericInterfaceImpl1 implements GenericInterface<String>{
@Override
public void method(String s) {
System.out.println(s);
}
}
实现类2
/*
含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型
类跟着接口走
就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型。
*/
public class GenericIntercfaceImpl2<I> implements GenericInterface<I> {
@Override
public void method(I i) {
System.out.println(i);
}
}
使用类:
public class Demo04GenericInterface {
public static void main(String[] args) {
GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1();
gi1.method("字符串");
//创建impl2对象
GenericIntercfaceImpl2<Integer> gi2 = new GenericIntercfaceImpl2<>();
gi2.method(10);
GenericIntercfaceImpl2<Double> gi3 = new GenericIntercfaceImpl2();
gi3.method(8.888);
}
}
6、泛型通配符(了解)
当使用泛型或者接口时,传递的数据中,泛型类型不确定可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
此时只能接受数据,不能往该集合中存储数据。