import java.util.ArrayList;
/*
泛型是JDK1.5使用的新特性
泛型的好处:
1.将运行时的异常提前至了编译时
2.泛型避免了无谓的强制类型转换
泛型在集合中的常见应用:
ArrayList<String> list = new ArrayList<String>();true 推荐使用
ArrayList<Object> list = new ArrayList<String>();false
ArrayList<String> list = new ArrayList<Object>();false
//以下两种写法主要为了解决新老系统的兼容性
ArrayList<String> list = new ArrayList();true
ArrayList list = new ArrayList<String>();true
注意:泛型没有多态的概念,作用两边的数据类型必须要一致,或者只写一边的泛型类型。
推荐使用:两边都写泛型
需求:把一个集合中元素全部转成大写
*/
public class Demo1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();//<String>表示该容器只能存放字符串类型的数据
list.add("aa");
list.add("bb");
list.add("cc");
for (int i = 0;i<list.size();i++){
String str = list.get(i);
System.out.println("转大写"+str.toUpperCase());
}
}
}
package cn.itcast.genrictiry;
/*
需求定义一个方法可以接收任意类型的参数,而且返回值类型必须要与实参的类型一致。
自定义泛型:自定义泛型就是一个数据类型的占位符或者是一个数据类型的变量。
方法上自定义泛型:
修饰符 <声明自定义的泛型>返回值类型 函数名(使用自定义泛型。。){
}
在泛型中不能使用基本数据类型,如果需要使用基本数据类型,那么就使用基本类型对应的包装类
byte-----> Byte
short----->Short
int------>integer
long----->Long
double ----->Double
float----->Float
boolean----->Boolean
char------>Character
方法泛型注意的事项:
1.在方法上自定义泛型,这个自定义泛型的具体数据类型是在调用该方法的时候传入实参的时候确定具体的数据类型的
2.自定义泛型只有符合标识符的命名规则即可,但是自定义泛型我们习惯使用一个大写字母表示。T Type E Element
*/
public class Demo2 {
public static void main(String[] args) {
String str= getData("aa");
Integer i = getData(123);
}
public static <T>T getData(T o){
return o;
}
}
package cn.itcast.genrictiry;
import java.util.ArrayList;
/*
需求:编写一个数组的工具类
泛型类:
泛型类的定义格式:
class 类<声明自定义泛型>{
}
泛型类要注意的事项:
1.在类上自定义泛型的具体数据类型是在使用该类的时候创建对象的时候确定的
2.如果一个类在类上已经声明了自定义泛型,如只使用该类型创建对象的时候没有指定泛型的具体数据类型,那么默认为Object类型
3.在类上自定义泛型不能作用于静态方法,如果静态的方法需要使用自定义泛型,那么需要在方法上自己声明使用
*/
class MyArrays<T>{
//元素翻转
public void reverse(T[] arr){
for(int startIndex = 0,endIndex = arr.length -1;startIndex<endIndex;startIndex++,endIndex++){
T temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
public String toString(T[] arr){
StringBuilder sb = new StringBuilder();
for(int i = 0;i<arr.length;i++){
if(i==0){
sb.append("["+arr[i]+",");
}else if(i==arr.length-1){
sb.append(arr[i]+"]");
}else{
sb.append(arr[i]+",");
}
}
return sb.toString();
}
public static <T>void print(T[] t){
}
}
public class Demo3 {
public static void main(String[] args) {
Integer[] arr = {10,12,14,19};
//创建数组的工具类对象
MyArrays<Integer> tool = new MyArrays<Integer>();
tool.reverse(arr);
System.out.println("数组的元素:"+tool.toString(arr));
MyArrays<String> tool2 = new MyArrays<String>();
String[] arr2 = {"aaa","bbb","ccc"};
tool2.reverse(arr2);
ArrayList<String> list = new ArrayList<String>();
}
}
package cn.itcast.genrictiry;
/*
泛型接口
泛型接口的定义格式:
interface 接口名<声明自定义泛型>{
}
如果要延长接口自定义泛型的具体数据类型,那么格式如下:
public class Demo4<T> implements Dao<T>{
}
泛型接口要注意的事项:
1.接口上自定义泛型的具体数据类型是在实现一个接口的时候指定的。
2.在接口上自定义的泛型如果在实现接口的时候没有指定具体的数据类型,那么默认是Object类型。
需求:目前我实现一个接口的时候,我还不明确我目前要操作的数据类型,我要等待创建接口实现类对象的时候我才能指定泛型的具体数据类型
*/
interface Dao<T>{
public void add(T t);
}
public class Demo4<T> implements Dao<T> {
@Override
public void add(T t) {
}
public static void main(String[] args) {
Demo4<String> d = new Demo4<String>();
}
}
package cn.itcast.genrictiry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
/*
泛型的上下限:
需求1:定义一个函数可以接收任意类型的集合对象。要求接收的集合对象只能存储Integer或者是Integer的父类类型数据。
需求2:定义一个函数可以接收任意类型的集合对象。要求接收的集合对象只能存储Number或者是Number的子类类型数据。
泛型中的通配符:?
? super Integer 只能存储Integer或者是Integer的父类类型数据(泛型的下限)
? extends Number 只能存储Number或者是Number的子类类型数据。(泛型的上限)
*/
public class Demo5 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
ArrayList<Number> list2 = new ArrayList<Number>();
HashSet<String> set = new HashSet<String>();
getData(list);
}
//泛型的上限
public static void getData(Collection<? extends Number> c){
}
//泛型的下限
public static void print(Collection<? super Integer> c){
}
}
package day17;
/*
单例集合的体系:
------|Collection 单例集合的根接口
-----------|List 如果实现了List接口的集合类,具备的特点:有序,重复
--------------|ArrayList 底层使用了Object数组实现的,特点:查询速度快,增删慢
--------------|LinkedList底层使用了链表数据结构实现的,特点:查询速度慢,增删快
--------------|Vector Vector的实现与ArrayList是一致的,但是线程安全,操作效率低。jdk1.0的时候出现的
-----------|set 如果是实现了Set接口的集合类,具备的特点:无序不可重复
--------------|HashSet 底层使用了一个哈希表支持的,特点:存取速度快,
HashSet添加元素的原理:
往HashSet添加元素的时候。首先HashSet会调用hashCode方法得到元素的哈希码值,然后会经过一系列运算就可以
算出该元素在哈希表中的存储位置
情况1:如果算出该元素的位置目前没有任何元素存储,那么该元素可以直接存储
情况2:如果算出该元素的位置目前已经存在其他元素,那么还会调用元素的equals方法与该位置的元素再比较一次。
如果equals方法返回的是false,那么该元素允许存储,如果equals方法返回的是true,那么该元素被视为重复元素,不允许存储。
--------------|TreeSet 底层是使用了红黑树(二叉树)数据结构实现的,特点:会对元素进行排序存储。
TreeSet 要注意的事项:
1。往TreeSet添加元素的时候,如果元素本身具备具备自然顺序的特性,那么会根据元素的自然顺序特性进行排序存储。
2.往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么元素所属的类必须要实现Comparable接口,把元素的比较规则
定义在CompareTo方法上。
3.往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而且元素所属的类没有实现Comparable接口,那么必须要在创建
TreeSet对象的时候传入比较器。
4.如果比较的方法(CompareTo 或者compare)返回的是0的时候,那么该元素被视为重复元素,不允许添加
比较器的定义格式:自定义一个类实现Comparator接口即可
class 类名 implements Comparator{
}
泛型:泛型是JDK1.5出现的新特性。
泛型的好处:
1.将运行时出现的问题提前至了编译时
2.避免了无谓的强制类型的转换。
自定义泛型:自定义泛型就是一个数据类型的占位符或者理解为一个数据类型的变量
泛型方法:
修饰符 <声明自定义的泛型> 返回值类型 函数名 (自定义的泛型 变量名)
泛型方法要注意的事项:
1.泛型方法中的自定义泛型的具体数据类型是在调用该函数的时候传入实参时确定的。
2.自定义泛型所用的表识符只要符合标识符的命名规则即可。但是我们习惯使用一个大写字母表示。
泛型类:
泛型类的格式:
class 类名<声明自定义的泛型>{
}
泛型类要注意的事项:
1.泛型类上的自定义泛型是在使用该类创建对象的时候指定具体的数据类型的
2.如果一个类已经自定义了泛型,使用该类创建对象的时候如果没有指定泛型的具体数据类型,那么默认为Object类型。
3.静态的函数不能使用类上自定义的泛型,如果静态函数需要使用,必须要在函数上自定义泛型。
泛型接口:
泛型接口的定义格式:
interface 接口名<声明自定义的泛型>{
}
泛型接口要注意的事项:
1.泛型接口上的自定义泛型是在实现该接口的时候指定具体数据类型的。
2.如果实现接口的时候没有指定接口上的自定义泛型的具体数据类型,那么默认是Object数据类型。
3.如果需要在创建接口实现类对象的时候才指定接口上自定义泛型,那么需要以下格式:class<T> 类名 implements 接口<自定义泛型>
泛型上下限:
?super Integer 允许Integer数据类型或者Integer父类类型 泛型下限
? extends Number 允许Number数据类型或者Number子类的数据类型 泛型上限。
*/
public class Demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}