1、昨日复习
Map存储数据的特点是什么?并指明key,value,entry存储数据的特点。
双列数据,存储key-value对数据。
key:无序的、不可重复的-àSet存储
value:无序的、可重复的–>Collection存储
key-value:无序的、不可重复àSet存储
2. 描述HashMap的底层实现原理(jdk 8版)Map中常用实现类有哪些?各自有什么特点?
如何遍历Map中的key-value对,代码实现
Collection和Collections的区别?

说明:ArrayList和HashMap都是线程不安全的,如果要求线程安全,我们可以将ArrayList和HashMap转换为线程的。使用synchronizedList(List list)和synchronizedMap(Map map)2、泛型
```java package com.atguigu.java;
import org.junit.Test;
import java.util.; / 泛型的使用 1、jdk5新增的特性
2、在集合中使用泛型: 总结: ①集合接口或集合类在jdk5时都修改为带泛型的结构 ②在实例化集合类时可以指明具体的泛型类型 ③指明完以后,在集合类或接口中凡是定义类或接口时,内部结构使用到类的泛型的位置,都指定为实例化时泛型类型。 比如:add(E e)—->实例化以后:add(Integer e) ④注意点:泛型的类型必须是类,不能是基本数据类型,需要用到基本数据类型的位置,拿包装类代替。 ⑤如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型。
3、如何自定义泛型结构:泛型类、泛型接口;泛型方法 3.1关于自定义泛型类、泛型接口: 如果定义了泛型类,实例没有指明类的泛型,则认为此泛型类型为Object类型 要求:如果定义了类是带泛型的,建议在实例化时要指明类的泛型。
子类在继承带泛型的父类时,指明了泛型类型。则实例化子类对象时,不需要指明泛型。泛型方法:在方法中出现了泛型的结构,泛型参数是与类的泛型参数没有任何关系。换句话说,泛型方法所属的类是不是泛型类都没有关系
*/ public class GenericTest { @Test //集合中使用泛型之前的情况: public void test1(){ int[] arr = new int[10]; ArrayList list = new ArrayList(); list.add(78); list.add(76); list.add(89); list.add(88); //问题一:类型不安全 list.add(“Tom”);
for (Object obj : list) {//问题二:强转时,可能出现ClassCastExceptionint stuObj = (Integer) obj;System.out.println(stuObj);}}//在集合中使用泛型的情况:@Testpublic void test2(){ArrayList<Integer> list = new ArrayList();list.add(78);list.add(76);list.add(89);list.add(88);//编译时就会进行类型检查,保证数据安全//方式一:/* for (Integer score:list) {//避免强转操作int stuScore = score;System.out.println(stuScore);}*///方式二:Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()){int subScore = (int)iterator.next();System.out.println(subScore);}}//在集合中使用泛型的情况:以HashMap为例:@Testpublic void test3(){Map<String,Integer> map = new HashMap<String,Integer>();map.put("Tom",87);map.put("Jerry",87);map.put("Jack",67);Set<Map.Entry<String, Integer>> entry = map.entrySet();Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();while (iterator.hasNext()){Map.Entry<String, Integer> e = iterator.next();String key = e.getKey();Integer value = e.getValue();System.out.println(key+"------"+value);}}
}
1.泛型类<br />(1)使用语法<br />类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();<br />(2)Java1.7以后,后面的<>中的具体的数据类型可以省略不写<br />类名<具体的数据类型> 对象名 = new 类名<>(); 菱形语法<br /><br />```javapackage com.atguigu.java2;import org.junit.Test;import java.util.ArrayList;import java.util.List;/*1、泛型在继承方面的体现2、通配符的使用*/public class GenericTest {/*** 1、泛型在继承方面的体现* 类A是类B的父类,G<A>和G<B>不具备子父类关系,二者是并列关系。* 补充:类A是类B的父类,A<G>是 B<G>的父类*/@Testpublic void test1(){Object obj = null;String str = null;obj = str;Object[] arr1 = null;String[] arr2 = null;arr1 = arr2;List<Object> list1 = null;List<String> list2 = null;//此时list1和list2的类型不具有子父类关系// list1 = list2;/*反证法:假设list1 = list2;*/}/*** 2、通配符的使用* 通配符:?*类A是类B的父类,G<A>和G<B>不具备子父类关系,二者是并列关系;二者共同的父类是:G<?>*/@Testpublic void test2(){List<Object> list1 = null;List<String> list2 = null;List<?> list = null;list = list1;list = list2;List<String> list3 = new ArrayList<>();list3.add("AA");list3.add("BB");list3.add("CC");list = list3;//添加:对于List<?>就不能向其内部添加数据。//除了添加null之外。// list.add("DD");//获取:允许读取数据,读取的数据类型为Object1。}}

泛型数组
经过查看sun的说明文档,在java中是”不能创建一个确切的泛型类型的数组”的。
也就是说下面的这个例子是不可以的:
List<String>[] ls = new ArrayList<String>[10];
而使用通配符创建泛型数组是可以的,如下面这个例子:
List<?>[] ls = new ArrayList<?>[10];
这样也是可以的:
List<String>[] ls = new ArrayList[10];
List<String>[] lsa = new List<String>[10]; // Not really allowed.Object o = lsa;Object[] oa = (Object[]) o;List<Integer> li = new ArrayList<Integer>();li.add(new Integer(3));oa[1] = li; // Unsound, but passes run time store checkString s = lsa[1].get(0); // Run-time error: ClassCastException.
这种情况下,由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList而不会出现异常,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。
而对泛型数组的声明进行限制,对于这样的情况,可以在编译期提示代码有类型安全问题,比没有任何提示要强很多。
下面采用通配符的方式是被允许的:数组的类型不可以是类型变量,除非是采用通配符的方式,因为对于通配符的方式,最后取出数据是要做显式的类型转换的。
List<?>[] lsa = new List<?>[10]; // OK, array of unbounded wildcard type.Object o = lsa;Object[] oa = (Object[]) o;List<Integer> li = new ArrayList<Integer>();li.add(new Integer(3));oa[1] = li; // Correct.Integer i = (Integer) lsa[1].get(0); // OK
————————————————
版权声明:本文为CSDN博主「VieLei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/s10461/article/details/53941091
