1、昨日复习

  1. Map存储数据的特点是什么?并指明key,value,entry存储数据的特点。
    双列数据,存储key-value对数据。
    key:无序的、不可重复的-àSet存储
    value:无序的、可重复的–>Collection存储
    key-value:无序的、不可重复àSet存储
    2. 描述HashMap的底层实现原理(jdk 8版)

  2. Map中常用实现类有哪些?各自有什么特点?

  3. 如何遍历Map中的key-value对,代码实现

  4. Collection和Collections的区别?
    QQ截图20220123140938.png
    说明: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类型 要求:如果定义了类是带泛型的,建议在实例化时要指明类的泛型。

  1. 子类在继承带泛型的父类时,指明了泛型类型。则实例化子类对象时,不需要指明泛型。
  2. 泛型方法:在方法中出现了泛型的结构,泛型参数是与类的泛型参数没有任何关系。
  3. 换句话说,泛型方法所属的类是不是泛型类都没有关系

*/ 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”);

  1. for (Object obj : list) {
  2. //问题二:强转时,可能出现ClassCastException
  3. int stuObj = (Integer) obj;
  4. System.out.println(stuObj);
  5. }
  6. }
  7. //在集合中使用泛型的情况:
  8. @Test
  9. public void test2(){
  10. ArrayList<Integer> list = new ArrayList();
  11. list.add(78);
  12. list.add(76);
  13. list.add(89);
  14. list.add(88);
  15. //编译时就会进行类型检查,保证数据安全
  16. //方式一:
  17. /* for (Integer score:list) {
  18. //避免强转操作
  19. int stuScore = score;
  20. System.out.println(stuScore);
  21. }*/
  22. //方式二:
  23. Iterator<Integer> iterator = list.iterator();
  24. while (iterator.hasNext()){
  25. int subScore = (int)iterator.next();
  26. System.out.println(subScore);
  27. }
  28. }
  29. //在集合中使用泛型的情况:以HashMap为例:
  30. @Test
  31. public void test3(){
  32. Map<String,Integer> map = new HashMap<String,Integer>();
  33. map.put("Tom",87);
  34. map.put("Jerry",87);
  35. map.put("Jack",67);
  36. Set<Map.Entry<String, Integer>> entry = map.entrySet();
  37. Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();
  38. while (iterator.hasNext()){
  39. Map.Entry<String, Integer> e = iterator.next();
  40. String key = e.getKey();
  41. Integer value = e.getValue();
  42. System.out.println(key+"------"+value);
  43. }
  44. }

}

  1. 1.泛型类<br />(1)使用语法<br />类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();<br />(2Java1.7以后,后面的<>中的具体的数据类型可以省略不写<br />类名<具体的数据类型> 对象名 = new 类名<>(); 菱形语法
  2. ![QQ截图20220123171837.png](https://cdn.nlark.com/yuque/0/2022/png/23186029/1642929553618-0309e47d-4a92-4da1-aa44-b2fff1c96764.png#clientId=u9f76bd8f-463e-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u5e1edbe3&margin=%5Bobject%20Object%5D&name=QQ%E6%88%AA%E5%9B%BE20220123171837.png&originHeight=668&originWidth=1248&originalType=binary&ratio=1&rotation=0&showTitle=false&size=325324&status=done&style=none&taskId=ub3b36ae8-f4c8-41f5-aef6-462af401196&title=)<br />![QQ截图20220123171852.png](https://cdn.nlark.com/yuque/0/2022/png/23186029/1642929560351-f8d38b3f-ee0d-4e12-a057-f6e21f4c5dcc.png#clientId=u9f76bd8f-463e-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u00592caf&margin=%5Bobject%20Object%5D&name=QQ%E6%88%AA%E5%9B%BE20220123171852.png&originHeight=665&originWidth=1292&originalType=binary&ratio=1&rotation=0&showTitle=false&size=269929&status=done&style=none&taskId=uf39fcce8-f63e-491c-8319-7a6533571ad&title=)<br />![QQ截图20220123174107.png](https://cdn.nlark.com/yuque/0/2022/png/23186029/1642930880585-a2920271-fb9a-425c-844a-0f35438a8ddd.png#clientId=u9f76bd8f-463e-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u60e3ab29&margin=%5Bobject%20Object%5D&name=QQ%E6%88%AA%E5%9B%BE20220123174107.png&originHeight=674&originWidth=1215&originalType=binary&ratio=1&rotation=0&showTitle=false&size=147742&status=done&style=none&taskId=u56e1953f-cf0d-4fe3-a6ac-3cded5502bb&title=)
  3. ```java
  4. package com.atguigu.java2;
  5. import org.junit.Test;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /*
  9. 1、泛型在继承方面的体现
  10. 2、通配符的使用
  11. */
  12. public class GenericTest {
  13. /**
  14. * 1、泛型在继承方面的体现
  15. * 类A是类B的父类,G<A>和G<B>不具备子父类关系,二者是并列关系。
  16. * 补充:类A是类B的父类,A<G>是 B<G>的父类
  17. */
  18. @Test
  19. public void test1(){
  20. Object obj = null;
  21. String str = null;
  22. obj = str;
  23. Object[] arr1 = null;
  24. String[] arr2 = null;
  25. arr1 = arr2;
  26. List<Object> list1 = null;
  27. List<String> list2 = null;
  28. //此时list1和list2的类型不具有子父类关系
  29. // list1 = list2;
  30. /*
  31. 反证法:
  32. 假设list1 = list2;
  33. */
  34. }
  35. /**
  36. * 2、通配符的使用
  37. * 通配符:?
  38. *类A是类B的父类,G<A>和G<B>不具备子父类关系,二者是并列关系;二者共同的父类是:G<?>
  39. */
  40. @Test
  41. public void test2(){
  42. List<Object> list1 = null;
  43. List<String> list2 = null;
  44. List<?> list = null;
  45. list = list1;
  46. list = list2;
  47. List<String> list3 = new ArrayList<>();
  48. list3.add("AA");
  49. list3.add("BB");
  50. list3.add("CC");
  51. list = list3;
  52. //添加:对于List<?>就不能向其内部添加数据。
  53. //除了添加null之外。
  54. // list.add("DD");
  55. //获取:允许读取数据,读取的数据类型为Object1。
  56. }
  57. }

QQ截图20220123203506.png


泛型数组

经过查看sun的说明文档,在java中是”不能创建一个确切的泛型类型的数组”的。

也就是说下面的这个例子是不可以的:

  1. List<String>[] ls = new ArrayList<String>[10];

而使用通配符创建泛型数组是可以的,如下面这个例子:

  1. List<?>[] ls = new ArrayList<?>[10];

这样也是可以的:

  1. List<String>[] ls = new ArrayList[10];

下面使用Sun的一篇文档的一个例子来说明这个问题:

  1. List<String>[] lsa = new List<String>[10]; // Not really allowed.
  2. Object o = lsa;
  3. Object[] oa = (Object[]) o;
  4. List<Integer> li = new ArrayList<Integer>();
  5. li.add(new Integer(3));
  6. oa[1] = li; // Unsound, but passes run time store check
  7. String s = lsa[1].get(0); // Run-time error: ClassCastException.

这种情况下,由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList而不会出现异常,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。
而对泛型数组的声明进行限制,对于这样的情况,可以在编译期提示代码有类型安全问题,比没有任何提示要强很多。
下面采用通配符的方式是被允许的:数组的类型不可以是类型变量,除非是采用通配符的方式,因为对于通配符的方式,最后取出数据是要做显式的类型转换的。

  1. List<?>[] lsa = new List<?>[10]; // OK, array of unbounded wildcard type.
  2. Object o = lsa;
  3. Object[] oa = (Object[]) o;
  4. List<Integer> li = new ArrayList<Integer>();
  5. li.add(new Integer(3));
  6. oa[1] = li; // Correct.
  7. Integer i = (Integer) lsa[1].get(0); // OK

————————————————
版权声明:本文为CSDN博主「VieLei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/s10461/article/details/53941091


尚硅谷宋红康第12章_泛型.pdf