1.泛型
1.1.泛型的定义,T 不指定类型的时候,就是Object类型。
public class TestGeneric<T> {
T x;
T y;
@Override
public String toString() {
return "TestGeneric{" +
"x=" + x +
", y=" + y +
'}';
}
public static void main(String[] args) {
TestGeneric<String> tg = new TestGeneric<String>();
tg.x = "10";
tg.y = "20";
System.out.println(tg);
}
}
1.2.泛型的注意点,
- 泛型的前后类型必须一致,1.7之后,后面的可以不写
- 泛型是没有继承的 ArrayList<Object> arrayList= new ArrayList<String>(); 报错。
- 泛型是语法糖,真正编译的时候,还是Object类型。(class 强转类型)
1.3.泛型类,
- 在类上面定义的泛型,创建的时候需要指定泛型的类型,没有指明就是Object类型。
- 泛型类中定义的泛型方法,不能使用在static修饰,因为静态方法是类名调用的,泛型在对象创建的时候才指定类型。
1.4.自定义泛型方法,方法单独使用泛型,必须得有参数才有意义。
public class TestGenericMethod {
<T> void test(T a) {
System.out.println(a.getClass());
}
static <E> void test2(E name) {
System.out.println(name.getClass());
}
public static void main(String[] args) {
TestGenericMethod genericMethod = new TestGenericMethod();
genericMethod.test("a");
TestGenericMethod.test2("haoren");
}
}
1.5.泛型通配符,只能作接收操作,不能做添加
public class TestWildcardCharacter {
static void test1(List<?> list) {
}
static void test2(List<? extends Number> list) {
}
static void test3(List<? super Number> list) {
}
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
test1(arrayList);
}
}
1.6.泛型的上限和下限,
- extends泛型的上限,用来限定元素的类型必须是Number的子类。
- super泛型的下限,用来限定元素的类型必须是Number的父类。
1.7.泛型的擦除,把泛型给去掉了,把原来有泛型的list赋值给没有泛型的list,泛型没有了。
2.list和数组的转换
- Arrays.asList转成集合之后不能添加和删除元素,而且把数组里面的元素整体当成一个对象。
- 一般不会把基本数据类型的数组转成集合,引用数据类型才去转成集合。
- new String[10] ,静态开辟空间。如果空间不够,自动创建和size一样大小的空间。
public class TestTransfer {
public static void main(String[] args) {
//数组转集合
int[] arr = {1, 2, 3, 4};
List<int[]> list=Arrays.asList(arr);
System.out.println(list);
Integer[] arr2 ={10,20,30,40};
List<Integer> list2=Arrays.asList(arr2);
System.out.println(list2);
//集合转数组
List<String> list3=new ArrayList<>();
list3.add("a");
list3.add("b");
Object[] obj=list3.toArray();
String[] strs=list3.toArray(new String[10]);
System.out.println(Arrays.asList(strs));
}
}
3.set是无序的(元素添加的顺序),不重复的,对象的去重,重写equals方法和hashCode方法,可以去重。
- HashSet
- TreeSet
4.hashCode,每一个对象都有一个hashCode值。跟内存地址对应的编号。每一个对象的hashCode值都不一样。
5.HashSet去重原理
- 每次调用add方法,添加对象的时候,每次都生成不同的hashcode值。
- 当添加的对象hashcode值相同的时候,才会调用equals方法,如果对象是相同的则返回false,不允许添加
6. LinkedHashSet
- 是HashSet的子类
- 底层是链表实现,保证元素怎么存怎么出。是Set集合唯一的保证顺序的集合。
7.随机生成10个1~20之间随机数,不重复,代码如下,
Random random = new Random();
TreeSet treeSet = new TreeSet();
while (treeSet.size()<10){
int num = random.nextInt(20) + 1;
treeSet.add(num);
}
System.out.println(treeSet.toString());
8.TreeSet用来对元素进行排序,按照数字大小,按照字母顺序,按照Unicode(包含了assic码)
- TreeSet存放的类型必须是相同的类型
- 自定义的对象不能添加到TreeSet当中,对象必须实现Comparable接口,并且重写compareTo方法
- compareTo的返回值,为0的话,只添加第一个元素,为正数,就是顺序添加,顺序显示,负数,就是倒序显示。
- 二叉树实现的,在添加元素的时候,会调用compareTo方法,返回正数就是 大于根元素,放在右边。
- 二叉树从左往右取
9.treeset添加自定义对象实例如下,自定义compareTo属性,源码TreeSet自定义属性比较
10.TreeSet比较器