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) {
//问题二:强转时,可能出现ClassCastException
int stuObj = (Integer) obj;
System.out.println(stuObj);
}
}
//在集合中使用泛型的情况:
@Test
public 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为例:
@Test
public 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 类名<>(); 菱形语法
![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=)
```java
package 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>的父类
*/
@Test
public 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<?>
*/
@Test
public 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 check
String 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