DAY16 泛型集合

一、泛型

1、泛型定义

​ 泛型(generics)是JDK5.0以后的特性,提供了编译期间安全监测机制,它是将数据类型参数化的一种方式。 例如:在对方法进行编写参数列表时,以前我们需要知道方法的参数类型 ,现在使用泛型机制可以将方法的参数类型也作为 “未知的类型” ,在调用该方法时传递该类型。

2、泛型的使用

2.1 泛型类(generic class)

​ 它是一种具有一个或多个类型变量的类,(一个变量可以有多种类型)

​ 语法

  public  class  类<T>{
      // 类里面的数据类型 和 方法返回值,以及方法的参数都可以使用T  
      // <>里面可以是任意大写字母
      
  }

public class People<T> {
    private T name;
    private T sex;

    public T getName() {
        return name;
    }
       public People(T name,T sex){
        this.name= name;
        this.sex = sex;
    }
    public People(){

    }
}
       // 创建没有指定泛型的对象 ,它默认是Object类型
        People  obj= new People();
        obj.setName("李四");
        System.out.println(obj);
        System.out.println(((String)obj.getName()).length());

        // 创建泛型类的对象
        People<String> people = new People<String>("张三","男");
        System.out.println(people);
        System.out.println(people.getName().length());

定义泛型的字母

T : Type: 变量类型

K: Key : 任意键的类型

V: Value : 任意值的类型

E:ELement 用于定义集合的元素类型

2.2 泛型接口(generic interface)

​ 在接口中定义泛型,使接口的方法可以使用该泛型,实现类实现该接口时需要指定接口的类型、

语法:

public interface Genarator<T> {
    public T getValue();

    public void setValue(T s);


}
public class StringGenarator implements  Genarator<String> {
   private String name;

    @Override
    public String getValue() {
        return name;
    }

    @Override
    public void setValue(String s) {
        this.name=s;
    }

public class StudentGenarator implements Genarator<Student> {
    private Student  stu;

    @Override
    public Student getValue() {
        return stu;
    }

    @Override
    public void setValue(Student s) {
        this.stu = s;
    }
}

泛型接口的好处:

​ 让接口的方法的返回值或参数类型 也参数化 (泛型)

2.3 泛型方法

​ a、为什么会使用泛型方法

​ 当一个类中 只有某个方法需要使用泛型,而不是类的全部方法使用泛型,这时可以将泛型定义的范围缩小,通常我们可以定义进行泛型方法。

b、定义泛型方法

​ 语法:

  public  class 普通类{
      
      public <T>  T  getValue(){
          
      }
      
      public <T> void setValue(T t){
          
      }  
      
  }
public class Convert {
    /**
     * 转成字符串的方法
     * @param <T> : 任意类型

     * @return
     */
    public <T> String convertString(T t){
        return  t.toString();
    }

    public <K,V> V converted(K k){
        return (V)k;// 强转的前提 是k -v 有关系
    }

泛型的好处:

​ 1、 可以对类的数据类型 写通用类型,提高代码的复用性 和 可扩展性

2.4 泛型通配符

​ 在定义泛型时除了可使用大写字母表示一种泛型类以外,还可以使用通配符表示泛型类型,如下三种表示方法

<?> :表示一种通用的泛型类,与相似 <? extends T> :表示 泛型类型是T的子类,或者是T <? super T> : 表示泛型类型是T的父类,或者是T 问题: <?> 与 的区别
  T t = new T() // 语法满足
  ? t = new ?()  // 语法不满足

​ 是一种确定的类型 , 可以表示定义泛型类或泛型方法

<?> 是一种不确定的类型, 不能定义泛型类或泛型方法, 通常用于作为方法的形参
public class Dept<T> {
    // 第一个员工
     private T first;
     // 第二个员工
     private T second;
public class Employee {
    private String ename;

    public String getEname() {
        return ename;
    }

public class Manager extends  Employee {

    // 通过经理对象 给经理赋值名称
    public Manager(String ename){
        super(ename);
    }

// 使用不确定的泛型类型 <?>

    /**
     *
     * 这里的部门的泛型可以是任意类型
     */
    public void showInfo(Dept<?> dept){

        System.out.println(dept.getFirst());

    }

    /**
     * @param dept 的泛型可以是Employee  或者继承自Employee
     * @param dept
     */
    public void showInfo2(Dept<? extends Employee> dept){

        System.out.println(dept.getFirst());
        System.out.println(dept.getSecond());

    }

    /**
     *
     * @param dept 的泛型必须是 Manager 或者 Manager的父类
     */
    public void showInfo3(Dept<? super Manager> dept){

        System.out.println(dept.getFirst());
        System.out.println(dept.getSecond());

    }

    public static void main(String[] args) {
         TestDept obj = new TestDept();

         //创建部门对象
        Dept<String> dept = new Dept();
        dept.setFirst("员工1");
        dept.setSecond("员工2");
         obj.showInfo(dept);

         // 在部门中添加 员工对象
        Dept<Employee> dept2 = new Dept();
        dept2.setFirst(new Employee("小强"));
        dept2.setSecond(new Employee("小花"));
        //这里的dept2的泛型是 Employee
        obj.showInfo2(dept2);

        Dept<Manager> dept3 = new Dept();
        dept3.setFirst(new Manager("张经理"));
        dept3.setSecond(new Manager("王经理"));
        //这里的dept3的泛型是  Manager
        obj.showInfo2(dept3);

        //  调用时 参数的泛型必须是 Manager 或Manager的父类
        obj.showInfo3(dept3);
        obj.showInfo3(dept2);
    }

二、集合框架

1、为什么会有集合?

存储多个元素我们以前学过数组类型, 由于数组类型特点是 相同类型且长度固定 ,如果需要存储某一天的新闻数据,用数组不合理 ,无法确定当天数量。 Java中提供可变长度的存储多个元素的数据类型,还可以存储不同数据结构的数据。这样的类型 就是“集合类型”

​ 数组和集合的区别?

​ a、数组的长度固定,集合的长度可自动扩容

​ b、数组的数据类型固定,集合可以存储任意类型 ,集合可以支持泛型

​ c、数组没有方法,而集合提供大量的方法

​ d、Java中提供一个动态数组 集合类型,或其他结合类型

2、集合的分布图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UjwUb43k-1603624803367)(D:/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9%20(2)]/20201023/%E7%AC%94%E8%AE%B0/assets/1591347967566.png)

2.1 集合的顶级接口: Collection

​ Collection属于单列集合的根接口,它扩展的主要子接口包括 java.util.List 和 java.util.Set接口,

List接口特点存储有序 且 可重复的元素, 而Set接口特点存储无序且不可重复的元素,其中List下扩展常用的实现类包括 java.util.ArrayList 和java.util.LinkedList 和Vector , 其中Set接口下扩展的实现类包括 java.util.HashSet 和 java.util.TreeSet .

​ 集合接口的常用方法:

  • public void add(E) : 把给定的元素添加到集合中

  • public void clear():清空集合中的所有元素

  • public boolean remove(E):删除集合中指定的元素,删除成功返回true

  • public boolean contains(E):判断该元素是否存在集合中

  • public boolean isEmpty():判断是否为空集合对象 null会报异常

  • public int size():获取几个元素的大小

  • publict Object toArray() : 将集合元素转成对象数组

    public static void main(String[] args) {
           //通过接口创建实现类 , 可指定存储的泛型
  
          Collection<String> collection = new ArrayList<String>();
          // 集合中指定了元素的类型  String
          collection.add("hello");  // 默认添加到末尾
          collection.add("hi");
          collection.add("哈哈");
          System.out.println("元素大小:"+ collection.size());
          // 删除集合元素  (后面的原始往前 移动)
          collection.remove("hi");
          System.out.println("元素大小:"+collection.size());
          System.out.println("第一个元素:"+((ArrayList<String>) collection).get(0));
          System.out.println("第二个元素:"+((ArrayList<String>) collection).get(1));
  
          // 判断元素是否存在
          System.out.println("是否存在哈哈:"+collection.contains("哈哈"));
          // 转成数组对象
          Object [] objs = collection.toArray();
          //遍历元素
          for(Object obj : objs){
              System.out.println("数组的元素:"+obj);
          }
          //清空元素  clear
          collection.clear();
          // 大小
          System.out.println("清空后元素的大小(对象依然存在,只能内容为空)"
                  +collection.size());
          // 判断对象中是否是空集合
          System.out.println(collection.isEmpty());
  
        
      }

Iterator 集合遍历接口

    // 直接对集合元素遍历   泛型只能是包装类
          Collection<Integer> scores = new ArrayList<>();
          scores.add(90);
          scores.add(88);
          scores.add(92);
          scores.add(91);
          //遍历集合  使用   ,
          // 再遍历集合时 不能一边遍历集合一边删除集合元素,这样会改变它的遍历的模式
          Iterator<Integer> is = scores.iterator();
          //判断是否有下一个元素   ,如果true ,则可以通过next获取值 
           while(is.hasNext()){
               Integer score = is.next();
               System.out.println(score);
           }
  
  • 2.2 ArrayList类

    ​ java.util.ArrayList是一个数组结构的集合,实现动态数组的功能,扩展所有Collection的方法

    数组结构的本质: 线性结构的顺序结构,ArrayList中使用连续的内存空间存储, 访问时通过下标(元素所在的位置)访问

2.2 ArrayList类:

​ java.util.ArrayList是一个数组结构的集合,实现动态数组的功能,扩展所有Collection的方法

数组结构的本质: 线性结构的顺序结构,ArrayList中使用连续的内存空间存储, 访问时通过下标(元素所在的位置)访问

ArrayList的数据结构

分析一个类的时候,数据结构往往是它的灵魂所在,理解底层的数据结构其实就理解了该类的实现思路,具体的实现细节再具体分析。

ArrayList的数据结构是:

img

说明:底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据。我们对ArrayList类的实例的所有的操作底层都是基于数组的。

​ 源码分析参考:https://www.cnblogs.com/zhangyinhua/p/7687377.html#_lab2_0_1

public static void main(String[] args) {
         //  通过ArrayList 创建集合对象
        // 还可以存储自定义对象  默认容量是 10
        ArrayList<String> list = new ArrayList<String>();
        // 存储有序集合
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        // 将元素插入到指定位置
        list.add(1,"ddd");
        //直接 遍历元素  get(Index) 通过下标访问元素
        for(int i = 0 ;i<list.size();i++){
            System.out.println("集合元素:"+ list.get(i));
        }
        // 设置集合的最小容量
        list.ensureCapacity(20);



    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值