集合(三)
泛型
- 泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
- 一提到参数,最熟悉的就是自定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
- 顾名思义,就是将类型由原来的具体的类型参数化,然后再使用/调用时传入具体的类型
- 这种参数类型可以用在类、方法和接口中,分别被称为泛型类,泛型方法、泛型接口
- 泛型定义格式
- <类型>:指定一种类型的格式。这里的类型可以看成是形参
- <类型1,类型2>:指定多种类型的格式,多种类型之间用逗号隔开,这里的类型可以看成是形参
- 将来具体调用的时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
- 泛型的好处:
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换
package FanXingDemo; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /* 需求 Collection集合存储字符串并遍历 */ public class FanXingDemo1 { public static void main(String[] args) { //创建集合对象 // Collection c = new ArrayList(); Collection<String> c = new ArrayList<String>(); c.add("hello"); c.add("java"); c.add("mei"); // c.add(100); // Iterator iterator = c.iterator(); Iterator<String> iterator = c.iterator(); while (iterator.hasNext()){ // Object next = iterator.next(); // String s = (String)next; //向下转型 //ClassCastException String s = iterator.next(); System.out.println(s); } } }
泛型类
- 泛型类的定义格式
- 格式:修饰符 class类名<类型>()
- 范例:public class Generic<T>()
- 此处的T可以是随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
定义一个泛型类
package FanXingDemo; public class Generic<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }
泛型类的使用
package FanXingDemo; public class GenericDemo { public static void main(String[] args) { Student s = new Student(); s.setName("钟启航"); System.out.println(s.getName()); Teacher t = new Teacher(); t.setAge(21); // t.setAge("20"); System.out.println(t.getAge()); System.out.println("-------------------"); Generic<String> g1 = new Generic<String>(); g1.setT("涛涛"); System.out.println(g1.getT()); Generic<Integer> g2 = new Generic<Integer>(); g2.setT(10); System.out.println(g2.getT()); Generic<Boolean> g3 = new Generic<Boolean>(); g3.setT(true); System.out.println(g3.getT()); } }
泛型方法
- 泛型方法的定义格式:
- 格式:修饰符<类型> 返回值类型 方法名(类型 变量名){}
- 范例:public<T>void show(T t){}
package FanXingDemo; //public class Generic1 { // public void show(String s ){ // System.out.println(s); // } // public void show(Integer i ){ // System.out.println(i); // } // public void shwo(Boolean b){ // System.out.println(b); // } // //} //public class Generic1<T> { // public void show(T t){ // System.out.println(t); // } //} // 泛型方法改进 public class Generic1{ public <T> void show (T t){ System.out.println(t); } }
泛型方法的使用
package FanXingDemo; public class Generic1Demo { public static void main(String[] args) { // Generic1 g = new Generic1(); // g.show("钟启航"); // g.show(21); // g.show(true); // g.show(12.34); // Generic1<String> g1 = new Generic1<String>(); // g1.show("钟启航"); // Generic1<Integer> g2 = new Generic1<Integer>(); // g2.show(21); // Generic1<Boolean> g3 = new Generic1<Boolean>(); // g3.show(true); Generic1 g = new Generic1(); g.show("钟"); g.show("21"); g.show(true); g.show(12.33); } }
泛型接口
- 泛型接口的定义格式:
- 格式:修饰符interface 接口名<类型>{}
- 范例:public interface Generic<T>{}
- 定义接口
package FanXingDemo; public interface Generic2<T> { void show(T t); }
- 定义接口实现类
package FanXingDemo; public class Generic2Impl<T> implements Generic2<T> { public void show(T t){ System.out.println(t); } }
- 测试
package FanXingDemo; public class GenericDemo2 { public static void main(String[] args) { Generic2<String> g1 = new Generic2Impl<String>(); g1.show("钟"); Generic2<Integer> g2 = new Generic2Impl<Integer>(); g2.show(21); } }
类型通配符
为了表示各种泛型List的父类,可以使用类型通配符
- 类型通配符:<?>
- List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
- 这种带通配符的List仅表示它是各种泛型List的父亲,并不能把元素添加到其中
如果说我们不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限
- 类型通配符上限:<?extends类型>
- List<?extends Number>: 它表示的类型是Number或者其他子类型
除了可以指定类型通配符的上限,也可以指定类型通配符的下限
- 类型通配符下限<?super类型>
- List<?super Number>: 它表示的类型是Number或者其父类型
package FanXingDemo; import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList; import java.util.ArrayList; import java.util.List; public class GenericeDemo3 { public static void main(String[] args) { //类型通配符:<?> List<?> list= new ArrayList<Object>(); List<?> list1 = new ArrayList<Number>(); List<?> list2 = new ArrayList<Integer>(); System.out.println("--------------------------"); //类型通配符上限<? extends 类型> // List<? extends Number> list3 = new ArrayList<Object>(); List<? extends Number> list3 = new ArrayList<Number>(); List<? extends Number> list4 = new ArrayList<Integer>(); System.out.println("-----------------------"); //类型通配下限,<? super类型> List<? super Number> list5 = new ArrayList<Object>(); List<? super Number> list6 = new ArrayList<Number>(); // List<? super Number> list7 = new ArrayList<Integer>(); } }
可变参数
- 可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
- 格式:修饰符 返回值类型 方法名(数据类型...变量名){}
- 范例:public static int sum(int...a){}
- 可变参数注意事项
- 这里的变量其实是一个数组
- 如果一个方法有多个参数,包含可变参数,可变参数要放在最后。
package FanXingDemo; public class ArgsDemo { public static void main(String[] args) { System.out.println(sum(10, 20)); System.out.println(sum(10, 20, 30)); System.out.println(sum(10, 20, 30, 40)); System.out.println(sum(10, 20, 30, 40, 50)); System.out.println(sum(10, 20, 30, 40, 50, 60)); System.out.println(sum(10, 20, 30, 40, 50, 60, 70)); } // public static int sum(int b,int ... a) { // return 0; // } public static int sum(int... a) { // System.out.println(a); // return 0; int sum = 0; for (int i : a) { sum += i; } return sum; } // public static int sum(int a ,int b){ // return a + b; // } // public static int sum(int a ,int b,int c){ // return a + b + c; // } // public static int sum(int a ,int b ,int c ,int d){ // return a + b + c + d ; // } }
可变参数的使用
- Array工具类中有一个静态方法:
- public static <T> List <T> asList(T...a):返回由指定数组支持的固定大小的列表
- List接口中有一个静态方法
- public sratic <E> List <E> of(E...elements):返回包含任意数量元素的不可变列表,在JDK9中
- Set接口中有一个静态方法
- public static <E>Set<E> of(E...elements):返回一个包含任意数量元素的不可变集合,在JDK9中
package FanXingDemo; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /* Array工具类中有一个静态方法: public static <T> List <T> asList(T...a):返回由指定数组支持的固定大小的列表 List接口中有一个静态方法 public sratic <E> List <E> of(E...elements):返回包含任意数量元素的不可变列表 在JDK9中 Set接口中有一个静态方法 public static <E>Set<E> of(E...elements):返回一个包含任意数量元素的不可变集合 在JDK9中 */ public class ArgsDemo2 { public static void main(String[] args) { // public static <T> List <T> asList(T...a):返回由指定数组支持的固定大小的列表 List<String> list = Arrays.asList("hello", "world", "hi"); // list.add("javaee");//UnsupportedOperationException 不支持请求操作 // list.remove("world");//UnsupportedOperationException list.set(1,"javaee"); System.out.println(list); } }
Map
- Map集合概述和使用
- Interface Map<K,V> K: 键的类型;V: 值的类型
- 将键映射到值的对象;不能包含重复的键;每个键可以映射到最多的一个值
- 举例:学生的学号和姓名
- ithema001 钟
- ithema002 王
- ithema003 李
- 创建Map集合的对象
- 多态的方式
- 具体的实现类HashMap
package Map; import java.util.HashMap; import java.util.Map; /* Map集合概述和使用 Interface Map<K,V> K: 键的类型;V: 值的类型 将键映射到值的对象;不能包含重复的键;每个键可以映射到最多的一个值 举例:学生的学号和姓名 ithema001 钟 ithema002 王 ithema003 李 创建Map集合的对象 多态的方式 具体的实现类HashMap */ public class MapDemo1 { public static void main(String[] args) { //创建集合对象 Map<String,String> map = new HashMap<String, String>(); //put(K key, V value) 将指定的值与该映射中的指定键相关联(可选操作)。 map.put("11","钟启航'"); map.put("12","航"); map.put("13","钟");// 添加元素 map.put("13","李");// 修改元素 System.out.println(map); } }
Map集合的基本功能

package Map; import java.util.HashMap; import java.util.Map; /* V put(K key, V value) 将指定的值与该映射中的指定键相关联(可选操作)。 V remove(Object key) 如果存在(从可选的操作),从该地图中删除一个键的映射。 void clear() 从该地图中删除所有的映射(可选操作)。 boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true boolean containsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true 。 boolean isEmpty() 如果此地图不包含键值映射,则返回 true 。 int size() 返回此地图中键值映射的数量。 */ public class MapDemo2 { public static void main(String[] args) { //创建集合对象 Map<String,String> map = new HashMap<String,String>(); // V put(K key, V value) 将指定的值与该映射中的指定键相关联(可选操作)。 map.put("H","L"); map.put("wuhu","yahu"); map.put("yihu","meihu"); // V remove(Object key) 如果存在(从可选的操作),从该地图中删除一个键的映射。 // System.out.println(map.remove("H")); // System.out.println(map.remove("s")); //void clear() 从该地图中删除所有的映射(可选操作)。 // map.clear(); //boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true // System.out.println(map.containsKey("H")); // System.out.println(map.containsKey("S")); //boolean containsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true 。 // System.out.println(map.containsValue("L")); // System.out.println(map.containsValue("S")); //boolean isEmpty() 如果此地图不包含键值映射,则返回 true 。 // System.out.println(map.isEmpty()); // int size() 返回此地图中键值映射的数量。 System.out.println(map.size()); System.out.println(map); } }
Map集合的获取功能

package Map; import com.sun.org.apache.xerces.internal.impl.xpath.XPath; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /* V get(Object key) 根据键获取值 Set<K>keySet() 获取所有键的集合 Collection<V>values() 获取所有值的集合 Set<Map,Entry<K,V>>entrySet() 获取所有键值对对象的集合 */ public class MapDemo3 { public static void main(String[] args) { //创建集合对象 Map<String,String> map = new HashMap<String, String>(); //添加元素 map.put("钟启航","梦梦"); map.put("李","钟"); map.put("涛","浪"); System.out.println(map.get("李")); System.out.println(map.get("芜湖")); // Set<K>keySet() 获取所有键的集合 // Set<String> keyset = map.keySet(); // for (String key : keyset){ // System.out.println(key); // } //Collection<V>values() 获取所有值的集合 Collection<String> values = map.values(); for (String value : values){ System.out.println(value); } } }
Map集合的遍历(方式1)
- Map集合中的操作
- 获取所有键的集合,用keySet()方法实现
- 遍历键的集合,获取到每一个键,用增强for实现
- 根据键去找值。用get(Object key)方法实现
package Map; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapDemo4 { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); map.put("钟启航","梦梦"); map.put("李","钟"); map.put("涛","浪"); Set<String> key = map.keySet(); for (String k : key){ String s = map.get(k); System.out.println(k+" "+s); } } }
Map集合遍历(方式2)
- Map集合中的操作
- 获取所有键值对对象的集合
- Set<Map,Entry<K,V>>entrySet()获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
- 用增强for实现,得到每一个Map.Entry
- 获取所有键值对对象的集合
- 根据键值对对象获取键和值
- 用getKey()得到键
- 用getValue()得到值
package Map; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapDemo5 { public static void main(String[] args) { Map<String,String> map = new HashMap<String, String>(); map.put("钟启航","梦梦"); map.put("李","钟"); map.put("涛","浪"); //获取所有键值对对象的集合 Set<Map.Entry<String, String>> entrySet = map.entrySet(); for ( Map.Entry<String, String> s : entrySet){ String key = s.getKey(); String value = s.getValue(); System.out.println(key+","+value); } } }
练习
package Map; import java.sql.SQLOutput; import java.util.HashMap; import java.util.Map; import java.util.Set; /* 需求:用HashMap集合,键是学号(String),值是学生对象(Student),存储三个键值对元素,并遍历 思路 定义学生类 创建HashMap集合对象 创建学生对象 把学生对象添加到集合 遍历集合 方式1:根据键找值 方式2:键值对对象找键和值 */ public class HashMapTest { public static void main(String[] args) { //创建HashMap集合对象 HashMap<String,Student> hs = new HashMap<String, Student>(); Student s1 = new Student("中",21); Student s2 = new Student("王",22); Student s3 = new Student("李",23); hs.put("001",s1); hs.put("002",s2); hs.put("003",s3); //方式一 Set<String> keySet = hs.keySet(); for (String key : keySet){ Student value = hs.get(key); System.out.println(key+","+value.getName()+","+value.getAge()); } System.out.println("--------------------------"); //方式2 Set<Map.Entry<String, Student>> entrySet = hs.entrySet(); for (Map.Entry<String, Student> s :entrySet){ String key = s.getKey(); Student value = s.getValue(); System.out.println(key+","+value.getName()+","+value.getAge()); } } }
TreeMap
- TreeMap:是基于红黑树的Map接口的实现
- HashMap<String,String>
- 键:String 值:String
package Map; import java.util.Map; import java.util.Set; import java.util.TreeMap; public class TreeMapDemo { public static void main(String[] args) { //创建集合对象 TreeMap<String, String> treeMap = new TreeMap<>(); //添加元素 treeMap.put("hello","你好"); treeMap.put("world","世界"); treeMap.put("Java","爪哇"); //遍历 Set<Map.Entry<String, String>> entryset = treeMap.entrySet(); for (Map.Entry<String, String> set : entryset){ String key = set.getKey(); String value = set.getValue(); System.out.println(key+"---"+value); } } }
package Map; import java.util.Comparator; import java.util.Map; import java.util.Set; import java.util.TreeMap; public class TreeMapDemo2 { public static void main(String[] args) { TreeMap<Student,String> map = new TreeMap<Student,String>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int i = o1.getAge() - o2.getAge(); int i2 = i == 0?o1.getName().compareTo(o2.getName()):i; return i2; } }); //创建学生对象集合 Student s1 = new Student("wuhu",21); Student s2 = new Student("yahu",22); Student s3 = new Student("xihu",23); map.put(s1,"long"); map.put(s2,"shu"); map.put(s3,"niu"); //遍历 Set<Map.Entry<Student, String>> entries = map.entrySet(); for (Map.Entry<Student, String> mapset : entries) { Student key = mapset.getKey(); String value = mapset.getValue(); System.out.println(key+"----------"+value); } } }
TreeMap练习
- "aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
- 分析:
- 1、定义一个字符串(可以改进用键盘录入)
- 2、定义一个TreeMap
- 键:Character
- 值:Integer
- 3、将字符串转换成字符数组
- 4、遍历字符数组,得到每一个字符
- 5、拿到字符作为键去集合中找值,看返回值
- 是null,说明该字符没有作为键存在,就把该字符作为键,value设置为1
- 不是null,说明该键存在,把value值加1,然后重新写回集合
- 6、定义一个StringBuilder作为拼接
- 7、遍历集合,得到键和值,按照a(5)b(4)c(3)d(2)e(1)要求拼接
- 8、把tringBuilder转换成String输出
- 分析:
- 输入:aababcabcdabcde
- 输出:a(5)b(4)c(3)d(2)e(1)
public class TreeMapDemo3 { public static void main(String[] args) { //定义一个字符串 // String s = "aababcabcdabcde"; Scanner sc = new Scanner(System.in); System.out.println("input String:"); String s = sc.next(); //定义一个TreeMap TreeMap<Character,Integer> map = new TreeMap<>(); //将字符串转换为字符数组 char[] chars = s.toCharArray(); //遍历字符数组,得到每一个字符 for (char ch : chars){ //拿到字符作为键去集合中找值,看返回值 Integer i = map.get(ch); //是null,说明该字符没有作为键存在,就把该字符作为键,value设置为1; if(i == null){ map.put(ch,1); }else { //不是null,说明该键存在,把value值加1,然后重新写回集合 i++; map.put(ch,i); } } //定义一个StringBuilder作为拼接 StringBuilder sb = new StringBuilder(); //遍历集合,得到键和值,按照a(5)b(4)c(3)d(2)e(1)要求拼接 Set<Map.Entry<Character, Integer>> set = map.entrySet(); for (Map.Entry<Character, Integer> entrset : set){ Character key = entrset.getKey(); Integer value = entrset.getValue(); sb.append(key).append("(").append(value).append(")"); } //把tringBuilder转换成String输出 String result = sb.toString(); System.out.println("result: " +result); } }
练习
需求:创建一个ArrayList集合,存储三个元素,每一个元素都是HashMap,每一个HashMap的键和值都是String ,并遍历
思路:
创建ArrayLIst集合
创建HashMap集合
把HashMap添加到ArrayList集合
遍历
package Map; import java.util.*; /* * 需求:创建一个ArrayList集合,存储三个元素,每一个元素都是HashMap,每一个HashMap的键和值都是String ,并遍历 * 思路: * 创建ArrayLIst集合 * 创建HashMap集合 * 把HashMap添加到ArrayList集合 * 遍历 * */ public class ArrayListAndHashMap { public static void main(String[] args) { //创建ArrayList集合 ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>(); //创建HashMap集合 HashMap<String,String> hashMap1 = new HashMap<String, String>(); hashMap1.put("芜湖","航"); hashMap1.put("呀呼","涛"); // 把HashMap添加到ArrayList集合 array.add(hashMap1); HashMap<String,String> hashMap2 = new HashMap<String, String>(); hashMap2.put("每户","磊"); hashMap2.put("途虎","强"); array.add(hashMap2); HashMap<String,String> hashMap3 = new HashMap<String, String>(); hashMap3.put("龙湖","虎"); hashMap3.put("驱虎","龙"); array.add(hashMap3); for (HashMap<String,String> hm : array){ Set<Map.Entry<String, String>> set = hm.entrySet(); for (Map.Entry<String, String> set1 : set ){ String key = set1.getKey(); String value = set1.getValue(); System.out.println(key+","+value); } } } }
需求:创建一个HashMap集合,存储三个键值对元素,每一个键值对元素的键是String,值是ArrayList,
每一个ArrayList的元素都是String,并遍历。
package Map; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; /* 需求:创建一个HashMap集合,存储三个键值对元素,每一个键值对元素的键是String,值是ArrayList, 每一个ArrayList的元素都是String,并遍历。 */ public class HashMapAndArrayList { public static void main(String[] args) { //创建HashMap集合 HashMap<String,ArrayList<String>> hashMap = new HashMap<String, ArrayList<String>>(); //创建ArrayList集合 ArrayList<String> arr1 = new ArrayList<String>(); arr1.add("钟"); arr1.add("梦"); hashMap.put("第一",arr1); ArrayList<String> arr2 = new ArrayList<String>(); arr2.add("涛"); arr2.add("凯"); hashMap.put("第二",arr2); ArrayList<String> arr3 = new ArrayList<String>(); arr3.add("磊"); arr3.add("涛"); hashMap.put("第三",arr3); // 第一种遍历方式 // Set<String> set = hashMap.keySet(); // for (String key : set){ // System.out.print(key+":"); // ArrayList<String> value = hashMap.get(key); // for (String s : value){ // System.out.print(s+","); // } // } //第二种遍历方式 Set<Map.Entry<String, ArrayList<String>>> entries = hashMap.entrySet(); for (Map.Entry<String, ArrayList<String>> hm : entries){ String s = hm.getKey(); System.out.print(s+":"); for (String value : hm.getValue()){ System.out.print(value+","+"\t"); } } } }

浙公网安备 33010602011771号