集合(三)

泛型

  • 泛型:是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");
            }
        }
    }
}


 
posted @ 2021-08-12 21:54  钟心意  阅读(60)  评论(0)    收藏  举报