集合框架

it2023-09-16  83

集合框架

1.体系介绍

集合体系,是java给我们提供一套用于存储引用数据类型的容器,各个接口实现类有不同的特点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fWTdIwQu-1603197168224)(.\img\集合体系结构1.png)]

2.Collection

Collection接口是List和Set的父接口,提供了一些常用的用于操作集合的增删改查的方法

3.List接口

List存储的一些有序的,不唯一的元素

3.1 ArrayList

ArrayList 集合特点

1.有序 可重复2.非线程安全的3.底层是一个Object类型的数组4.使用无参构造初始化ArrayList表示初始化一个空的数组当我们第一次添加元素的时候,集合的长度修改为105.扩容是原来的1.5倍6.删除元素也涉及到移动位置 并且删除是将元素设置为null 等待垃圾回收ArrayList 因为有下标 查询快 可以直接根据下标来查询元素因为有下标 增删慢 因为对集合内容的修改 必须最后保证数组的数据结构完整性 package com.qfedu.test1; import java.util.ArrayList; import java.util.Date; /** * ArrayList集合 * 泛型 <这里指定类型> 表示集合中的类型只能为泛型类型 * add() 添加 * remove() 删除 * set() 修改 * get() 查询 * isEmpty() 是否为空 * clear() 清空集合 * size() 长度 * @author WHD * */ public class Test2 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(20); list.add("abc"); list.add(3.14); list.add('a'); ArrayList<Integer> list1 = new ArrayList<Integer>(); // list1.add("a"); 因为泛型是Integer 所以只能添 Integer ArrayList<String> list2 = new ArrayList<String>(); list2.add("a"); // 泛型中只能写引用数据类型 ArrayList<News> listNews = new ArrayList<News>(); listNews.add(new News("周末竟然在家和女朋友做这种事1", "赵四1", "在家蒸馒头1", new Date())); listNews.add(new News("周末赵四家里两日游", "广坤", "和赵四吵架", new Date())); listNews.add(new News("周末竟然在家和女朋友做这种事", "赵四", "在家蒸馒头", new Date())); listNews.add(new News("周末赵四家里两日游", "广坤", "和赵四吵架", new Date())); listNews.add(new News("周末竟然在家和女朋友做这种事", "赵四", "在家蒸馒头", new Date())); listNews.add(new News("周末赵四家里两日游", "广坤", "和赵四吵架", new Date())); listNews.add(new News("周末竟然在家和女朋友做这种事", "赵四", "在家蒸馒头", new Date())); listNews.add(new News("周末赵四家里两日游", "广坤", "和赵四吵架", new Date())); listNews.add(new News("周末竟然在家和女朋友做这种事", "赵四", "在家蒸馒头", new Date())); listNews.add(new News("周末赵四家里两日游", "广坤", "和赵四吵架", new Date())); System.out.println("集合长度" + listNews.size()); listNews.add(new News("周末竟然在家和女朋友做这种事", "赵四", "在家蒸馒头", new Date())); listNews.add(new News("周末赵四家里两日游", "广坤", "和赵四吵架", new Date())); System.out.println("集合长度" + listNews.size()); // 删除 会返回删除掉的元素 System.out.println(listNews.remove(0)); System.out.println("集合长度" + listNews.size()); // 修改 根据下标 会返回修改的元素 System.out.println(listNews.set(10, new News("周末赵四家里两日游2", "广坤2", "和赵四吵架2", new Date()))); // 查询 根据下标 System.out.println(listNews.get(10)); // 当前集合是否为空 System.out.println(listNews.isEmpty()); // 清空集合 // listNews.clear(); // 当前集合是否为空 System.out.println(listNews.isEmpty()); News n1 = new News("标题1", "作者1", "内容1", new Date()); listNews.add(0, n1); System.out.println("集合长度" + listNews.size()); System.out.println(listNews.get(1)); System.out.println(listNews.indexOf(n1)); } }

ArrayList遍历与耗时

package com.qfedu.test2; import java.util.ArrayList; import java.util.Iterator; /** * ArrayList遍历 * 1.普通for循环遍历 * 2.迭代器方式遍历 * @author WHD * */ public class Test2 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(20); list.add(30); list.add(50); list.add(70); list.add(90); // 方式1 普通for循环 for(int i = 0; i < list.size();i++) { System.out.println(list.get(i)); } System.out.println("========================"); // 方式2 迭代器方式 Iterator<Integer> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } System.out.println("========================"); // 方式3 增强for循环 (JDK1.5新特性 底层实现依然是迭代器 相当于迭代的简化版) for(Integer i : list) { System.out.println(i); } } } package com.qfedu.test2; import java.util.ArrayList; import java.util.Iterator; /** * ArrayList * 三种遍历方式 耗时 * @author WHD * */ public class Test3 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < 200000; i++) { list.add(i); } long startTime = System.currentTimeMillis(); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } long endTime = System.currentTimeMillis(); System.out.println("普通for耗时" + (endTime - startTime)); startTime = System.currentTimeMillis(); Iterator<Integer> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } endTime = System.currentTimeMillis(); System.out.println("迭代器耗时" + (endTime - startTime)); startTime = System.currentTimeMillis(); for(Integer i : list) { System.out.println(i); } endTime = System.currentTimeMillis(); System.out.println("增强for循环耗时" + (endTime - startTime)); } }
3.2 LinkedList

LinkedList 提供了与ArrayList相同的API,不同的实现,还提供了独有的用于操作头部 和 尾部的方法

1.Linked是基于双向链表的实现2.没有初识大小 也不涉及扩容3.无序 没有下标 元素内容不能重复4.线程不安全的5.查询慢 增删快 因为没有下标 不需要移动元素 查询慢 同样也是因为没有下标 不能下标来一次就查找到想要的内容 package com.qfedu.test5; import java.util.LinkedList; /** * LinkedList 提供了与ArrayList相同的API,不同的实现,还提供了独有的用于操作头部 和 尾部的方法 * 1.Linked是基于双向链表的实现 * 2.没有初识大小 也不涉及扩容 * 3.无序 没有下标 元素内容不能重复 * 4.线程不安全的 * 5.查询慢 增删快 因为没有下标 不需要移动元素 查询慢 同样也是因为没有下标 不能下标来一次就查找到想要的内容 * @author WHD * */ public class Test1 { public static void main(String[] args) { LinkedList list = new LinkedList(); list.add("a"); list.add(20); list.add('a'); LinkedList<String> list1 = new LinkedList<String>(); list1.add("a"); list1.add("b"); list1.add("c"); list1.add("d"); list1.add("e"); list1.add("r"); list1.add("f"); list1.add("g"); list1.add("t"); System.out.println(list1.size()); // list1.remove(); // 等价于调用 removeFirst() 方法 list1.remove(0); list1.removeFirst(); // 删除链表头部 list1.removeLast(); // 删除链表尾部 System.out.println(list1.get(0)); list1.getFirst();// 获取链表头部 list1.getLast(); // 获取链表尾部 最后一个元素 list1.set(0, "hello"); System.out.println(list1.isEmpty()); list1.clear(); System.out.println(list1.size()); } }

LinkedList遍历

package com.qfedu.test5; import java.util.Iterator; import java.util.LinkedList; /** * LinkedList遍历方式 * 1.普通for循环 (强烈不推荐) * 2.增强for循环 * 3.迭代器 * @author WHD * */ public class Test2 { public static void main(String[] args) { LinkedList<Integer> list = new LinkedList<Integer>(); for (int i = 0; i < 200000; i++) { list.add(i); } // long beginTime = System.currentTimeMillis(); // // 方式1 普通for循环遍历 // for (int i = 0; i < list.size(); i++) { // System.out.println(list.get(i)); // } // long endTime = System.currentTimeMillis(); // System.out.println("普通for循环耗时" + (endTime - beginTime)); // // 方式2 增强for循环遍历 // long beginTime = System.currentTimeMillis(); // for (Integer i : list) { // System.out.println(i); // } // long endTime = System.currentTimeMillis(); // System.out.println("增强for循环耗时" + (endTime - beginTime)); // 方式3 迭代器 long beginTime = System.currentTimeMillis(); Iterator<Integer> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } long endTime = System.currentTimeMillis(); System.out.println("迭代器遍历耗时" + (endTime - beginTime)); } }
3.3 Vector

Vector特点

1.无参构造 直接初始化一个长度为10的数组2.扩容是原来的两倍3.线程安全的 package com.qfedu.test4; import java.util.Vector; /** * Vector特点 * 1.无参构造 直接初始化一个长度为10的数组 * 2.扩容是原来的两倍 * 3.线程安全的 * @author WHD * */ public class Test1 { public static void main(String[] args) { Vector<String> vector = new Vector<String>();// 无参构造 直接初始化一个长度为10的数组 vector.add("a"); vector.add("b"); vector.add("c"); vector.add("d"); System.out.println("第一次元素个数" + vector.size()); vector.remove(0); // 删除第一个元素 vector.set(0, "B"); // 修改元素 System.out.println("删除一个元素以后" + vector.size()); System.out.println(vector.get(0)); // 获取元素 System.out.println(vector.isEmpty()); // 是否为空 vector.clear(); // 清空元素 } }

4.Set接口

4.1 HashSet

HashSet

1.Set接口常用的实现类之一2.HashSet底层是一个HashMap 使用的是HashMap中的key3.无序 非线程安全 不能重复 可以为null package com.qfedu.test1; import java.util.HashSet; import java.util.Iterator; /** * HashSet * 1.Set接口常用的实现类之一 * 2.HashSet底层是一个HashMap 使用的是HashMap中的key * 3.无序 非线程安全 不能重复 可以为null * @author WHD * */ public class Test1 { public static void main(String[] args) { HashSet set = new HashSet(); set.add("a"); set.add(20); HashSet<String> set1 = new HashSet<String>(); set1.add("A"); set1.add("A"); set1.add("B"); set1.add("C"); set1.add("D"); System.out.println(set1.contains("A")); // 是否包含A 包含返回true 否则false System.out.println(set1.size()); set1.remove("A"); System.out.println(set1.size()); // 没有修改的方法 // 没有获取单个元素的方法 System.out.println(set1.isEmpty()); // 是否为空 // set1.clear(); System.out.println("========================="); // 遍历方式1 迭代器 Iterator<String> it = set1.iterator(); while(it.hasNext()) { System.out.println(it.next()); } System.out.println("========================="); // 遍历方式2 增强for循环 for(String str : set1) { System.out.println(str); } } }

HashSet去重复的原理

1.两个对象的equals方法比较为true 并且 hashCode相等 才认为是重复的内容 不能进行添加

package com.qfedu.test1; import java.util.HashSet; /** * 学生类 * @author WHD * */ public class Student { private String name; private String idCard; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIdCard() { return idCard; } public void setIdCard(String idCard) { this.idCard = idCard; } public Student() { } public Student(String name, String idCard) { this.name = name; this.idCard = idCard; } @Override public String toString() { return "Student [name=" + name + ", idCard=" + idCard + "]"; } public boolean equals(Object obj) { if(this == obj) { return true; } if(obj instanceof Student) { Student stu = (Student) obj; if(this.getName().equals(stu.getName()) && this.getIdCard().equals(stu.getIdCard())) { return true; } } return false; } public int hashCode() { int prime = 31; int result = 1; result = prime * result + this.getName() == null ? 0 : this.getName().hashCode(); result = prime * result + this.getIdCard() == null ? 0 : this.getIdCard().hashCode(); return result; } /** * HashSet去重复原理 * 1.两个对象的equals方法比较为true 并且 hashCode相等 才认为是重复的内容 不能进行添加 * @param args */ public static void main(String[] args) { HashSet<Student> set = new HashSet<Student>(); Student stu1 = new Student("赵四", "4612318751212132"); Student stu2 = new Student("赵四", "4612318751212132"); set.add(stu1); set.add(stu2); System.out.println(set.size()); } }
4.2 LinkedHashSet

LinkedHashSet 可以保证元素的顺序 插入顺序

1.不能重复 唯一 可为null2.线程不安全3.可以保证顺序4.底层依然是一个HashSet 而HashSet底层就是HashMap package com.qfedu.test2; import java.util.Iterator; import java.util.LinkedHashSet; /** * LinkedHashSet 可以保证元素的顺序 插入顺序 * 1.不能重复 唯一 可为null * 2.线程不安全 * 3.可以保证顺序 * 4.底层依然是一个HashSet 而HashSet底层就是HashMap * @author WHD * */ public class Test2 { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<String>(); set.add("20"); set.add("10"); set.add("33"); set.add("2"); set.remove("10"); set.contains("10"); set.isEmpty(); set.clear(); for(String i : set) { System.out.println(i); } System.out.println("========================="); Iterator<String> it = set.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }
4.3 TreeSet

TreeSet

一个有序的(按照我们自己指定的比较规则升序顺序)Set集合 底层是一个 TreeMap要求TreeSet中的元素必须实现Comparable接口 重写compareTo方法 package com.qfedu.test5; import java.util.TreeSet; /** * TreeSet * 一个有序的(按照我们自己指定的比较规则升序顺序)Set集合 底层是一个 TreeMap * 要求TreeSet中的元素必须实现Comparable接口 重写compareTo方法 * @author WHD * */ public class Test2 { public static void main(String[] args) { TreeSet<String> set1 = new TreeSet<String>(); set1.add("A"); set1.add("Z"); set1.add("F"); set1.add("G"); set1.add("S"); for(String str : set1) { System.out.println(str); } TreeSet<Person> set2 = new TreeSet<Person>(); set2.add(new Person("赵四", 17)); set2.add(new Person("刘能", 19)); set2.add(new Person("广坤", 15)); for(Person p : set2) { System.out.println(p); } } }

5.Map接口

5.1 HashMap

Map接口的实现类

HashMap集合无序键和值都允许为null值可以重复键不能重复 也就是说只能有一个键为null 重复对已经存在的键设置值 将覆盖原来值初识的数组长度是16 负载因子是0.75 表示数组的使用率达到75% 将扩容 package com.qfedu.test2; import java.util.HashMap; /** * Map接口的实现类 * HashMap集合 * 无序 * 键和值都允许为null * 值可以重复 * 键不能重复 也就是说只能有一个键为null 重复对已经存在的键设置值 将覆盖原来值 * 初识的数组长度是16 负载因子是0.75 表示数组的使用率达到75% 将扩容 * * @author WHD * */ public class Test1 { public static void main(String[] args) { HashMap map1 = new HashMap(); map1.put("a", 10); map1.put(20, 'a'); HashMap<String,String> map2 = new HashMap<String,String>(); map2.put("CN", "中国"); map2.put("RU", "俄罗斯"); map2.put("US","美国"); map2.put("KR", "韩国"); map2.put("JP", "小日本"); map2.put("JP", "日本"); map2.put(null, null); System.out.println(map2.size()); System.out.println("删除的元素值是" + map2.remove("JP")); System.out.println("替换的内容" + map2.replace("CN", "中华人民共和国")); System.out.println("根据键获取值" + map2.get("CN")); System.out.println("集合长度" + map2.size()); System.out.println("集合是否为空" + map2.isEmpty()); map2.clear(); System.out.println("集合是否为空" + map2.isEmpty()); } }

HashMap遍历

package com.qfedu.test3; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; /** * HashMap遍历 * 1.获取到所有的key * 2.获取到所有的value * 3.获取到所有的键值对组合 是一个Entry Entry是一个类 每一对键值对都属于Entry类型的对象 包含键和值 * 4.获取到所有的键值对组合的迭代器 * @author WHD * */ public class Test1 { public static void main(String[] args) { HashMap<Integer,String> map2 = new HashMap<Integer,String>(); map2.put(1, "中国"); map2.put(2, "俄罗斯"); map2.put(3,"美国"); map2.put(4, "韩国"); map2.put(5, "小日本"); // 方式1 获取所有的键 Set<Integer> keySet = map2.keySet(); for(Integer key : keySet) { System.out.println("键是" + key + "值是" + map2.get(key)); } System.out.println("==============================="); // 方式2 获取所有的value Collection<String> values = map2.values(); for(String value : values) { System.out.println("值是" + value); } System.out.println("==============================="); // 方式3 获取所有键值对组合 Set<Entry<Integer, String>> entrySet = map2.entrySet(); for(Entry<Integer,String> en : entrySet) { System.out.println(en.getKey() + en.getValue()); } // 方式4 获取所有的键值对组合的迭代器 Iterator<Entry<Integer, String>> iterator = map2.entrySet().iterator(); while(iterator.hasNext()) { Entry<Integer, String> next = iterator.next(); System.out.println(next.getKey()); System.out.println(next.getValue()); } } }

数据结构

原来我们学习的集合,两种数据结构(ArrayList数组,LinkedList链表)

我们发现以上两种数据结构 刚好是互补的,那么有没有一种新的集合可以将以上两者结合有的 HashMap就是 将两者进行结合 实现增删改查效率都很高 只是理想状态 实际上并不会这样完美 比如HashMap比较占地方JDK1.7 数组 + 单向链表JDK1.8 数组 + 单向链表 + 红黑树HashMap默认长度 数组的长度 16 负载因子 0.75 当数组使用率达到75% 扩容两倍HashMap 存储过程:1.根据key的hashCode来计算出当前元素应该存放在数组中哪个位置2.如果此位置已经有元素存在 那么接着向下延伸为单向链表3.JDK8中当链表的长度超过8时 将链表改为红黑树 用于缓解链表下元素过多 所带来的查询慢的问题扩容是原来的两倍 resize();
5.2Hashtable

HashMap跟 Hashtable 有相同的API

Hashtable1.线程安全的2.初识容量为11 数组3.扩容是两倍+ 1 rehash(); package com.qfedu.test4; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * * HashMap跟 Hashtable 有相同的API * Hashtable * 1.线程安全的 * 2.初识容量为11 数组 * 3.扩容是两倍+ 1 rehash(); * @author WHD * */ public class Test2 { public static void main(String[] args) { Map<String,String> map = new Hashtable<String,String>(); map.put("1", "a"); map.put("2", "b"); map.put("3", "c"); // System.out.println(map.size()); // map.remove("1"); // map.replace("2", "B"); // System.out.println(map.get("2")); System.out.println("================================"); // 方式1 获取所有的key Set<String> keys = map.keySet(); for(String key : keys) { System.out.println(key + map.get(key)); } System.out.println("================================"); // 方式2 获取所有的value Collection<String> values = map.values(); for (String string : values) { System.out.println(string); } System.out.println("================================"); // 方式3 获取所有Entry 每一项 Set<Entry<String, String>> entrySet = map.entrySet(); for(Entry<String,String> en : entrySet) { System.out.println(en.getKey() + en.getValue()); } System.out.println("================================"); // 方式4 获取Entry迭代器 alt + shift + l 生成对应的类型来接收表达式 Iterator<Entry<String, String>> it = map.entrySet().iterator(); while(it.hasNext()) { System.out.println(it.next().toString()); } // map.put(null, null); } }
5.3 Properties

Properties 也是Map集合的实现类

此类用于记录配置文件信息,所以只可以存储键和值均为字符串,所以不能使用put方法添加元素,必须使用setPropertie()方法

package com.qfedu.test4; import java.util.Properties; /** * Properties 也是Map集合 * @author WHD * */ public class Test3 { public static void main(String[] args) { Properties properties = System.getProperties(); properties.list(System.out); System.out.println("==============================="); System.getProperties(); System.out.println(properties.get("java.version")); Properties p = new Properties(); p.put(1,"a"); p.setProperty("a", "a"); p.setProperty("b", "a"); p.setProperty("1", "a"); p.setProperty("2", "a"); p.setProperty("3", "a"); } }
5.4 TreeMap

TreeMap 可以排序的Map集合

顺序是按照比较器比较的升序要求TreeMap中的键必须实现Comparable接口 重写compareTo方法1.有序的2.线程安全的 package com.qfedu.test5; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; /** * TreeMap 可以排序的Map集合 * 顺序是按照比较器比较的升序 * 要求TreeMap中的键必须实现Comparable接口 重写compareTo方法 * 1.有序的 * 2.线程安全的 * * @author WHD * */ public class Test1 { public static void main(String[] args) { TreeMap<String,String> map = new TreeMap<String,String>(); map.put("b", "赵四1"); map.put("f", "赵四2"); map.put("z", "赵四3"); map.put("r", "赵四4"); map.put("a", "赵四5"); Set<Entry<String, String>> entrySet = map.entrySet(); for(Entry<String, String> entry : entrySet) { System.out.println(entry.toString()); } TreeMap<Person,String> personMap = new TreeMap<Person,String>(); personMap.put(new Person("赵四", 17), "赵四喜欢尬舞"); personMap.put(new Person("广坤", 15), "广坤擅长口技"); personMap.put(new Person("刘能", 19), "刘能擅长口吃"); Set<Entry<Person, String>> entrySet2 = personMap.entrySet(); for(Entry<Person,String> entry : entrySet2) { System.out.println(entry.toString()); } } }

6.Collections工具类

Collections 工具类 提供了用于操作集合的方法

max() 最大值min() 最小值binarySearch() 二分查找 要求必须先排序sort() 排序 升序 package com.qfedu.test4; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Collections 工具类 * max() 最大值 * min() 最小值 * binarySearch() 二分查找 要求必须先排序 * sort() 排序 升序 * @author WHD * */ public class Test1 { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(20); list.add(40); list.add(60); list.add(10); list.add(99); System.out.println(Collections.max(list)); System.out.println(Collections.min(list)); Collections.sort(list); System.out.println(list.toString()); System.out.println(Collections.binarySearch(list, 10)); // 如果不排序不能保证下标的准确性 List<Student> stuList = new ArrayList<Student>(); stuList.add(new Student("赵四", "1454787211454121", 20)); stuList.add(new Student("广坤", "5698445464612121", 17)); stuList.add(new Student("刘能", "5678241564613111", 22)); Collections.sort(stuList); System.out.println(stuList.toString()); } }

Comparable接口 比较器接口

当集合中的泛型为自定义类型是时,如果需要排序,那么泛型类必须实现Comparable接口,重写compareTo方法

package com.qfedu.test4; /** * 学生类 * @author WHD * */ public class Student implements Comparable<Student>{ private String name; private String idCard; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIdCard() { return idCard; } public void setIdCard(String idCard) { this.idCard = idCard; } public Student() { } public Student(String name, String idCard,int age) { this.name = name; this.idCard = idCard; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", idCard=" + idCard + "]"; } @Override public int compareTo(Student stu) { // 这里按照我们自己指定的规则来比较 比如 按照年龄 // 相等0 当前大于其他 1 当前小于其他 -1 if(this.getAge() == stu.getAge()) { return 0; }else if(this.getAge() > stu.getAge()) { return 1; } return -1; } }

7. 泛型

泛 型

作用:统一数据类型 方便代码的管理 和 扩展List<类型A> 表示此list集合只能存储A类型的对象泛型的应用场景 1.类 2.接口 3.形参 4.返回值 泛型的表示字母 可以随意写 大小写都可以 但是我们要求都要大写 而且通常是单词首字母比如: 1. K key 键 2. V value 值 3. E element 元素 4. R return 返回值 5. P parameter 参数 6. T type 类型 泛型相当于一个占位符 先占一个位置 不具体是什么类型 我们在实例化的时候 指定是什么类型 那么泛型就指代什么类型泛型不能转型 泛型不能多态 package com.qfedu.test3; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * 泛 型 * 作用:统一数据类型 方便代码的管理 和 扩展 * List<类型A> 表示此list集合只能存储A类型的对象 * 泛型的应用场景 * 1.类 * 2.接口 * 3.形参 * 4.返回值 * 泛型的表示字母 可以随意写 大小写都可以 但是我们要求都要大写 而且通常是单词首字母 * 比如: * 1. K key 键 * 2. V value 值 * 3. E element 元素 * 4. R return 返回值 * 5. P parameter 参数 * 6. T type 类型 * * 泛型相当于一个占位符 先占一个位置 不具体是什么类型 我们在实例化的时候 指定是什么类型 那么泛型就指代什么类型 * 泛型不能转型 泛型不能多态 * @author WHD * */ public class Test1 { public static void main(String[] args) { A a = new A(); A<String> a1 = new A<String>(); a1.m1("a"); B<String> b1 =new BImpl(); b1.m1(); B<Integer> b2 = new BImpl1(); b2.m1(); } } class A<E>{ void m1(E e) { } E m2() { return null; } public static <T> T m3(T t) { return t; } } interface B<T>{ T m1(); } class BImpl implements B<String>{ @Override public String m1() { return null; } } class BImpl1 implements B<Integer>{ @Override public Integer m1() { return null; } } class Animal{ } class Dog extends Animal{} class Cat extends Animal{} class TestAnimal{ public static void m1(Set<String> set) { } public static void m2(Set<? extends Animal> set) { } public static void m3(List<? super Dog> list) { } public static Map<String,Set<? extends Animal>> m4(){ return null; } public static void m5(List<Animal> list) { } public static void main(String[] args) { m2(new HashSet<Dog>()); m2(new HashSet<Cat>()); m2(new HashSet<Animal>()); // m5(new ArrayList<Dog>()); 类型不匹配 因为形参是父类 子类不能充当父类的泛型 m3(new ArrayList<Dog>()); m3(new ArrayList<Animal>()); // m3(new ArrayList<Cat>()); } } interface C<P,R>{ R m1(P p); } class CImpl implements C<String,Integer>{ @Override public Integer m1(String p) { return null; } }

{ void m1(E e) {

} E m2() { return null; } public static <T> T m3(T t) { return t; }

}

interface B{ T m1(); }

class BImpl implements B{

@Override public String m1() { return null; }

}

class BImpl1 implements B{ @Override public Integer m1() { return null; } }

class Animal{

}

class Dog extends Animal{}

class Cat extends Animal{}

class TestAnimal{

public static void m1(Set<String> set) { } public static void m2(Set<? extends Animal> set) { } public static void m3(List<? super Dog> list) { } public static Map<String,Set<? extends Animal>> m4(){ return null; } public static void m5(List<Animal> list) { } public static void main(String[] args) { m2(new HashSet<Dog>()); m2(new HashSet<Cat>()); m2(new HashSet<Animal>());

// m5(new ArrayList()); 类型不匹配 因为形参是父类 子类不能充当父类的泛型

m3(new ArrayList<Dog>()); m3(new ArrayList<Animal>()); // m3(new ArrayList<Cat>()); }

}

interface C<P,R>{ R m1(P p); }

class CImpl implements C<String,Integer>{

@Override public Integer m1(String p) { return null; }

}

a
最新回复(0)