泛型 : 本质是参数化类型,把类型作为参数来进行传递。
常见泛型 : 泛型类、泛型接口、泛型方法。
语法 : <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 接口。