java 泛型 和集合容器
1.1 泛型的安全机制
泛型作用 : 强制了集合存储固定的数据类型,例如就不会存在一个集合又存字符串又存数值类型。
泛型的书写格式 :
集合类<存储的数据类型> 变量名 = new 集合类<存储的数据类型>(); // 类型可以不写:钻石操作符
使用泛型的好处 :
-
安全性提高
-
代码量减少
-
避免了类型的强制转换
-
程序的问题,由运行时期,提前到编译时期
1.2 泛型中的 E 问题
E没有什么实际价值,只是一个变量而已
特殊 : 等待接收指定的数据类型
1 2 3 | ArrayList<E> //创建对象 ArrayList<String> al = new ArrayList<String>(); // E 不再是E了,变成String |
1.3 自定义泛型类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class Factory<QQ> { private QQ q; public void setQ(QQ q){ this .q = q;} public QQ getQ(){ return q; } } public static void main(String[] args) { Factory<String> factory = new Factory<String>(); factory.setQ( "abc" ); String s = factory.getQ(); System.out.println(s); Factory<Double> factory2 = new Factory<Double>(); factory2.setQ( 1.5 ); Double q = factory2.getQ(); System.out.println(q); } |
1.4 泛型方法
1 2 3 4 5 6 7 8 9 10 | public class Factory<Q> { public static <T> void staticMethod(T q){ System.out.println(q); } public void print(Q q){ System.out.println(q); } } |
1.5 泛型接口
-
实现类实现接口,不实现泛型
-
实现类实现接口,同时指定泛型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //泛型接口 public interface Inter <T> { public abstract void inter(T t); } /** * 实现接口,不理会泛型 * 对象创建的时候,指定类型 */ public class InterImpl<T> implements Inter<T>{ public void inter(T t){ System.out.println(t); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * 实现接口,同时指定泛型 */ public class InterImpl2 implements Inter<String> { public void inter(String s) { System.out.println( "s==" +s); } } public class GenericTest { public static void main(String[] args) { Inter<String> in = new InterImpl<String>(); in.inter( "ok" ); Inter in2 = new InterImpl2(); in2.inter( "kkk" ); } } |
1.6 泛型通配符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //泛型的通配符 public class GenericTest { public static void main(String[] args) { List<String> stringList = new ArrayList<String>(); stringList.add( "abc" ); stringList.add( "bbc" ); List<Integer> integerList = new ArrayList<Integer>(); integerList.add( 1 ); integerList.add( 2 ); each(stringList); each(integerList); } /** * 定义方法,可以同时迭代器 遍历这两个集合 * 方法的参数,是要遍历的集合,不确定是哪个集合 * 定义参数,写接口类型,不要写实现类 */ public static void each(List<?> list){ Iterator<?> it = list.iterator(); while (it.hasNext()){ Object obj = it.next(); System.out.println(obj); } } } |
1.7 泛型限定
-
<? extends Company> 传递类型可以是Company或者是他的子类
-
<? extends E> 传递E类型或者是 E 的子类,泛型上限限定
-
<? super E > 传递E类型或者是E的父类,泛型下限限定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public static void main(String[] args) { //创建集合,存储员工对象 //开发部的 List<Development> devList = new ArrayList<Development>(); //存储开发部员工对象 Development d1 = new Development(); d1.setName( "张三" ); d1.setId( "开发部001" ); Development d2 = new Development(); d2.setName( "张三2" ); d2.setId( "开发部002" ); devList.add(d1); devList.add(d2); //财务部集合 List<Financial> finList = new ArrayList<Financial>(); Financial f1 = new Financial(); f1.setName( "李四" ); f1.setId( "财务部001" ); Financial f2 = new Financial(); f2.setName( "李四2" ); f2.setId( "财务部002" ); finList.add(f1); finList.add(f2); System.out.println(devList); System.out.println(finList); each(devList); each(finList); // List<Integer> integerList = new ArrayList<>(); // integerList.add(1); // each(integerList); } /** * 要求 : 定义方法 * 同时遍历2个集合 * 遍历的同时取出集合元素,调用方法work() * ? 接收任何一个类型 * 只能接收 Company和子类对象 * 明确父类,不能明确子类 */ public static void each(List<? extends Company> list){ Iterator<? extends Company> it = list.iterator(); while (it.hasNext()){ //取出元素 Company obj =it.next(); obj.work(); } } |
2 Map集合
java.util.Map接口,是双列集合的顶级接口.在一个Map的集合容器中,键保证唯一性,不包含重复键,每个键只能对应一个值
2.1 Map接口方法
-
boolean containsValue(V)判断集合是否包含这个值,包含返回true
-
V remove(K)移除指定的键值对,返回被移除之前的值
-
Collection<V> values() Map集合中的所有的值拿出,存储到Collection集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public static void mapMethod(){ //创建集合,键是整数,值是String Map<Integer,String> map = new HashMap<Integer, String>(); map.put( 1 , "a" ); map.put( 2 , "b" ); map.put( 3 , "c" ); map.put( 4 , "d" ); map.put( 5 , "e" ); //boolean containsKey(K)判断集合是否包含这个键,包含返回true boolean b = map.containsKey( 1 ); System.out.println( "集合中包含键:" +b); //boolean containsValue(V)判断集合是否包含这个值,包含返回true b = map.containsValue( "c" ); System.out.println( "集合中包含值:" +b); //size()返回集合的长度 int size = map.size(); System.out.println( "集合长度:" +size); //V remove(K)移除指定的键值对,返回被移除之前的值 String value = map.remove( 1 ); System.out.println( "被删除之前的:" +value); System.out.println(map); //Collection<V> values() Map集合中的所有的值拿出,存储到Collection集合 Collection<String> coll = map.values(); for (String s : coll){ System.out.println(s); } } |
2.2 Map集合的遍历
2.2.1 键找值
-
实现思想 :
-
Map接口定义了方法 keySet() 所有的键,存储到Set集合
-
遍历Set集合
-
取出Set集合元素 Set集合的元素是Map集合的键
-
Map集合方法get()传递键获取值
-
2.2.2 键值对映射关系
-
实现思想 :
-
Map接口的方法 Set< Map.Entry<Key,Value> > entrySet()
-
方法返回Set集合,集合中存储的元素,比较特别
-
存储的是Map集合中,键值对映射关系的对象 , 内部接口 Map.Entry
-
-
遍历Set集合
-
取出Set集合的元素
-
是Map.Entry接口对象
-
接口的对象方法: getKey() ,getValue()
-
-
2.3. HashMap
-
特点:
-
哈希表结构
-
保证键唯一性,用于键的对象,必须重写hashCode,equals方法
-
线程不安全集合,运行速度快
-
合运行使用null,作为键或者值
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public static void hashMap2(){ Map<Person,String> map = new HashMap<Person, String>(); map.put( new Person( "a" , 20 ), "广东" ); map.put( new Person( "b" , 22 ), "香港" ); map.put( new Person( "b" , 22 ), "贵港" ); map.put( new Person( "c" , 24 ), "澳门" ); map.put( new Person( "d" , 26 ), "深圳" ); System.out.println( "map = " + map); } public static void hashMap1(){ Map<String, Person> map = new HashMap<String, Person>(); map.put( "a" , new Person( "张三" , 20 )); map.put( "b" , new Person( "张三" , 20 )); map.put( "c" , new Person( "张三" , 20 )); map.put( null , null ); for (String key : map.keySet()){ System.out.println(key+ "===" +map.get(key)); } for (Map.Entry<String,Person> entry : map.entrySet()){ System.out.println(entry.getKey()+ "===" +entry.getValue()); } |
2.4 LinkedHashMap
LinkedHashMap继承HashMap实现Map接口,LinkedHashMap底层实现原理是哈希表,双向链,存取有序. 其它的特性和父类HashMap一样.
2.5 Hashtable
Map接口的实现类Hashtable, Hashtable类诞生于JDK1.0版本, Map接口诞生于JDK1.2版本. Hashtable类从JDK1.2开始,改进为实现Map接口
-
Hashtable类的特点
-
底层数据结构是哈希表
-
线程安全的,运行速度慢,被更加先进的HashMap取代
-
不允许null值,null键, 存储null直接抛出空指针异常
-
2.6 Vector集合类
List接口的实现Vector,命运和Hashtable一样.
-
Vector类的特点
-
底层实现结构是数组
-
数组的默认容量是10,每次扩容是原来的长度*2
-
线程安全,运行速度慢,被ArrayList取代
-
2.7 TreeMap集合
-
TreeMap集合的特点
-
底层实现是红黑树结构 (添加查询速度比较快)
-
存储到TreeMap中元素,对键进行排序
-
排序依据 :
-
对象的自然顺序,作为键的对象,实现了接口Comparable
-
自己提供比较器,实现接口Comparator,优先级高
-
-
线程不安全的,运行速度快
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public static void treeMap2(){ Map<Student,String> map = new TreeMap<Student, String>( new MyCom() ); map.put( new Student( "a" , 20 ), "广东" ); map.put( new Student( "b" , 19 ), "广西" ); System.out.println( "map = " + map); } public static void treeMap1(){ Map<Person,String> map = new TreeMap<Person, String>(); map.put( new Person( "a" , 20 ), "广东" ); map.put( new Person( "b" , 19 ), "广西" ); System.out.println( "map = " + map); } class MyCom implements Comparator<Student>{ public int compare(Student s1, Student s2){ return s1.getAge() - s2.getAge(); } } public int compareTo(Person p){ return this .age - p.age; } |
2.8 ConcurrentHashMap
ConcurrentHashMap类本质上Map集合,键值对的集合.使用方式和HashMap没有区别.
凡是对于此Map集合的操作,不去修改里面的元素,不会锁定,线程安全
2.9 Properties
-
Properties集合特点
-
继承Hashtable,实现Map接口
-
底层是哈希表结构
-
线程是安全的,运行速度慢
-
集合没有泛型的写法,键和值的数据类型锁定为String类型
-
集合有自己的特有方法
-
此集合可以和IO流对象结合使用,实现数据的持久存储
-
方法和IO相关 : load(输入流)
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public static void prop3(){ Properties prop = new Properties(); prop.setProperty( "a" , "1" ); prop.setProperty( "b" , "2" ); prop.setProperty( "c" , "3" ); Set<String> set = prop.stringPropertyNames(); for (String key : set){ System.out.println(key + "==" + prop.getProperty(key)); } } public static void prop2(){ Properties prop = new Properties(); prop.setProperty( "a" , "1" ); prop.setProperty( "b" , "2" ); prop.setProperty( "c" , "3" ); System.out.println(prop); String value = prop.getProperty( "a" ); System.out.println(value); } public static void prop1(){ Properties prop = new Properties(); prop.setProperty( "a" , "1" ); prop.setProperty( "b" , "2" ); prop.setProperty( "c" , "3" ); System.out.println(prop); } |
本文作者:Ziper1076443011
本文链接:https://www.cnblogs.com/Ziper1076443011/p/16267809.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步