泛型 : 本质是参数化类型,把类型作为参数来进行传递。
常见泛型 : 泛型类、泛型接口、泛型方法。
语法 : <T,...> T成为类型占位符,表示一个引用类型。
好处 : 1. 提高代码的重用性
2.防止类型转换异常,提高代码的安全性。
1. 泛型类(Generic)
1.不能实例化,不能new为对象。原因是数据类型不确定,有可能构造方法私有等原因。
测试类,主方法
package Genertic; public class Test { public static void main(String[] args) { //使用泛型类创建对象 Test01<String> test01 = new Test01<String>(); test01.t = "hello"; test01.show("nihao"); String t = test01.getT(); Test01<Integer> test02 = new Test01<Integer>(); test02.t = 100; test02.show(100); Integer t1 = test02.getT(); } }
Test泛型类方法
package Genertic; //泛型类 public class Test01<T> { //使用泛型T创建变量 T t; //添加方法,作为方法的参数 public void show(T t){ System.out.println(t); } //泛型作为方法的返回值 public T getT(){ return t; } }
2. 泛型接口
总接口
package Genertic; //接口名<T> //泛型不能创建静态常量 public interface Test02<T> { String name = "张三"; T server (T t); }
接口方法一 : 直接把泛型类确定为字符串类型
package Genertic; public class MyInterfaceImpl implements Test02<String>{ @Override public String server(String t) { System.out.println(t); return t; } }
接口方法二 : 泛型类还是泛型类
package Genertic; public class MyInterfaceimpl2<T> implements Test02<T>{ @Override public T server(T t) { System.out.println(t); return t; } }
测试类,主方法。
package Genertic; public class Test { public static void main(String[] args) { //如果一开始确定为字符串类型,那在这里就不用声明了。 MyInterfaceImpl impl = new MyInterfaceImpl(); impl.server("你好"); //如果泛型类一开始没确定,那么在这里就要确定 MyInterfaceimpl2<Integer> impl2 = new MyInterfaceimpl2<Integer>(); impl2.server(110); } }
个人总结 :假如是接口二的话,一开始不固定类型,那么再后来确定类型可以确定成很多种,
但是要是接口一的话,那只能是字符串类型了,因为一开始就固定为字符串类型了。
有点像抽象类和接口一样。
3. 泛型方法
泛型方法
package Genertic; //泛型方法 //语法 :<T> 返回值类型 public class Method { //泛型方法 public <T> void show(T t){ System.out.println("泛型方法"+t); } }
Test主方法
//泛型方法 Method method = new Method(); method.show("你好"); method.show(123); method.show(3.14);
总结 :泛型方法中的最后类型是看传进去什么参数决定的,传进的参数是什么类型那么就是什么类型。
4. 泛型集合
概念 :参数化类型、类型安全的集合、强制集合元素类型必须一致。
特点 :1. 编译时就可以检查,并非运行时抛出异常。
访问时,不必类型转换。
不同泛型引用之间不能相互赋值,泛型不存在多态。
5. Set集合
Set子接口特点 :无序、无下标、元素不可重复。
1、Set实现类
Hash Set : 基于Hash Code实现元素不重复。
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
Tree Set : 基于排列顺序实现元素不重复。
package Set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; //测试set接口的使用 public class Demo1 { public static void main(String[] args) { //创建集合 Set<String> set = new HashSet<>(); //1.添加数据 set.add("苹果"); set.add("桃子"); set.add("菠萝"); System.out.println("数据个数" + set.size()); System.out.println(set.toString()); //2.删除数据 set.remove("苹果"); System.out.println(set); //3.遍历 //增强for循环 for (String string:set) { System.out.println(string); } //使用迭代器 Iterator it = set.iterator(); while (it.hasNext()){ String str = (String) it.next(); System.out.println(str); } //判断 System.out.println(set.contains("菠萝")); System.out.println(set.isEmpty()); } }
6. Hash Set的使用
基于Hash Code计算元素存放位置。
当存入元素的哈希码相同时,会调用equals来进行确定,如果结果为true,则拒绝后者存入。
package Set; import java.util.HashSet; import java.util.Iterator; //HashSet的使用,存储结构 :数组+链表+红黑树 public class Demo2 { public static void main(String[] args) { //新建集合 HashSet<String> hashSet = new HashSet<String>(); hashSet.add("拼过"); hashSet.add("努力过"); hashSet.add("奋斗过"); System.out.println(hashSet.size()); System.out.println(hashSet); //删除数据 hashSet.remove("拼过"); System.out.println(hashSet); //遍历 for (String string:hashSet) { System.out.println(string); } Iterator<String> it = hashSet.iterator(); while (it.hasNext()){ System.out.println(it.next()); } //判断 System.out.println(hashSet.contains("努力过")); System.out.println(hashSet.isEmpty()); } }
7. Tree Set 的使用
基于排列顺序实现元素不重复。
实现了Sorted Set接口,对集合元素自动排序。
元素对象的类型必须实现Comparable接口,指定排序规则。
通过Compare To方法确定是否元素重复。
8. Hash Map 的使用
Hash Map 是一个散列表,它存储的内容是键值对(key-value)映射。
Hash Map 实现了 Map 接口,根据键的 Hash Code 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
Hash Map 是无序的,即不会记录插入的顺序。
Hash Map 继承于Abstract Map,实现了 Map、Cloneable、java.io.Serializable 接口。