JAVA核心编程1

collection集合

1.1集合概述

集合:集合是java中提供的一种容器,可以用来存储多个数据。 ​ 集合和数组既然都是容器,他们有啥区别? ​

1.java中数组的长度是固定的,集合的长度是可变的。

​ 2.数组存储的是同一类型的元素,可以存储基本数据类型值,也可以存储引用数据类型。集合中存储的都是对象,而且对象的类型可以不一致,在开发中一般当对象多的时候,使用集合进行存储。

1.2 集合框架

集合按照其存储结构可以分为两大类,分别是单列集合java.util.collection和双列集合java.util.Map。

collection: 单列集合的根接口。用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是ListSet接口,List接口特点是元素有序,元素可以重复。Set接口的特点是元素无序,并且不能重复。List接口主要的实现类有arrayList和linkedList,set接口主要的实现类有HashSet和TreeSet。

1.2.1 collection集合体系图

 

注意:

在学习使用集合的时候,学习顶层接口/抽象类中的共性方法,因为所有的子类都能使用。

在学习使用集合的时候,使用底层,因为顶层不是接口就是抽象类,不能创建对象使用,需要使用底层的子类创建对象使用

1.2.2 常用集合的底层及特点

集合名

底层实现原理

特点

ArrayList

数组

查询快,增删慢

LinkedList

链表

增删快,查询慢

vector(了解)

数组

和arrayList类似,但是线程安全

HashSet

哈希表+红黑树

无索引,不可存储重复元素,存取无序

LinkedHashSet

哈希表+链表

无索引,不可存储重复元素,保证存取顺序

TreeSet(了解)

二叉树

一般就用于排序

1.3collection常用功能

所有单列集合的最顶层接口,里面定义了所有单列集合共性的方法,任意的单列集合都可以使用collection中的方法。

共性方法:

1.public boolean add(E e) 把给定的对象添加到当前的集合中

2.​ public void clear() 清空集合中所有的元素

3.​ public boolean remove(E e) 把给定的元素在当前集合中删除

4.​ public boolean contains(E e) 判断当前集合中是否包含给定的对象 ​

5.public boolean isEmpty() 判断当前集合是否为空

6.​ public int size() 返回集合中元素的个数 ​

7.public Object[] toArray() 把集合中的元素,存储到数组中,并返回

代码演示:

 public static void main(String[] args) {
        //首先创建集合对象 使用多态形式
        Collection<String> coll = new ArrayList<>();
//        public boolean add(E e) 把给定的对象添加到当前的集合中
          boolean b1 = coll.add("张三");   //true
        coll.add("张二");
        System.out.println(b1);
        System.out.println(coll);
//       public void clear()  清空集合中所有的元素
//
//       public boolean remove(E e) 把给定的元素在当前集合中删除
         boolean b2 = coll.remove("李四");
        System.out.println(b2);   //false
//       public boolean contains(E e) 判断当前集合中是否包含给定的对象
        System.out.println(coll.contains("lisi"));
        System.out.println(coll.contains("张三"));
//       public boolean isEmpty()  判断当前集合是否为空
        System.out.println(coll.isEmpty());
//       public int size() 返回集合中元素的个数
        System.out.println(coll.size());
//        coll.clear();
//        System.out.println(coll.size());
//        public Object[] toArray() 把集合中的元素,存储到数组中,并返回
        Object[] objects = coll.toArray();
        for(int i=0;i<objects.length;i++){
            System.out.println(objects[i]);
        }
    }

 

iterator迭代器

1.概述

在程序开发中,经常需要遍历集合中的所有元素,因为有的集合没有索引,不能使用普通的for循环遍历,针对这种需求jdk专门提供了一个接口java.util.Iterator接口。Iterator接口也是java集合中的一员,但它 与collection、map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)collection中的元素,因此iterator对象也被称为迭代器对象。

1.1迭代的概念

迭代:即collection集合元素的通用获取方式,在取元素之前要先判断该集合中有没有元素,如果有,就把这个元素取出来,继续再判断,如果还有就再取出来,一直把集合中的所有元素全部取出,这种取出方式专业术语叫迭代。

1.2获取迭代器的方法

public Iterator iterator() 获取集合对应的迭代器,用来遍历集合中的元素

1.3 iterator接口中的方法

1.public E next() 判断集合中还有没有下一个元素,有就返回该元素,没有就报异常。

2.​ public boolean hasNext() 如果仍有元素可以迭代,则返回true

代码演示:

public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> coll = new ArrayList<>();
        //添加元素
        coll.add("科比");
        coll.add("麦迪");
        coll.add("卡特");
        coll.add("艾佛森");
        //System.out.println(coll);
        //多态形式获取Iterator对象
        Iterator<String> it = coll.iterator();
        //取出一个元素
        String s = it.next();
        //System.out.println(s);
        //循环取出所有元素
        while (it.hasNext()){
            String str = it.next();
            System.out.println(str);
        }
        System.out.println("-----------------------");
        for(Iterator<String> it2=coll.iterator();it2.hasNext();){
            String e = it2.next();
            System.out.println(e);
        }
    }

注意:

1.Iterator接口也是有泛型的,迭代器的泛型是跟着集合走,集合是什么泛型,迭代器就是什么泛型。

  1. 发现使用迭代器取出集合中元素的代码,是一个重复的过程,所以我们可以使用循环优化,

不知道集合中有多少元素,使用while循环,循环结束的条件是hashNext方法返回false

  1. 在进行集合元素取出时,如果集合中已经没有元素了,还继续使用next方法,将会发生NoSuchElementException异常

泛型

1.1 泛型概述

在前面学习的集合概念中,我们都知道集合中也可以存储任意类型对象,只要把对象存储集合后,那么这时候都会被提升为object类型。当我们在取出每一个对象,并且进行相应的操作,这时候就必须要类型转换。

代码:

public class GenericDemo {
    public static void main(String[] args) {
        Collection coll = new ArrayList();
        coll.add("abc");
        coll.add(123);   //由于集合中没有做任何限定 任何类型都可以在其中存储
        coll.add("hqyj");
        Iterator it = coll.iterator();
        while (it.hasNext()){
            //需要打印字符串的长度 就要把迭代出来的元素转换成String类型对象
            String str = (String)it.next();
            System.out.println(str.length());
        }
    }
}

上述代码在运行时,会报ClassCastException异常。

1.1.1 使用泛型主要是在我们不清楚需要什么数据类型的时候使用

注意:

1.泛型可以在类或者方法中预支的使用未知的类型

2.一般在对象创建的时候,将未知的类型确定具体的类型,当没有指定泛型时,默认为object类型。

1.2 泛型的好处与弊端

使用泛型

不使用泛型

好处

1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型 2.把运行时期异常提升到了编译期

集合不使用泛型,默认的是object类型,可以存储任意类型的元素

弊端

泛型是什么类型,只能存储什么类型的数据

不安全,有可能引发异常

1.3 定义和使用具有泛型的类

格式:修饰符 class 类名<代表泛型的变量> {} 代码:

public class MyGenericClass<MVP>{
    //没有MVP类型,在这里代表未知的一种数据类型,未来传递什么类型就是什么类型
    private MVP mvp;

    public void setMvp(MVP mvp){
        this.mvp=mvp;
    }
    public MVP getMvp(){
        return mvp;
    }
}
测试类:
public static void main(String[] args) {
        //创建一个泛型为String的类
        MyGenericClass<String> my = new MyGenericClass<>();
        //调用setMvp
        my.setMvp("安东尼-戴维斯");
        //调用getMvp
        System.out.println(my.getMvp());
        //创建一个泛型为Integer的类
        MyGenericClass<Integer> my2 = new MyGenericClass<>();
        my2.setMvp(123);
        System.out.println(my2.getMvp());
    }

1.4 定义和使用具有泛型的方法

格式: 修饰符 返回值类型 方法名(参数列表){

//方法体

}

代码:

public class GenericMethod {
    //定义一个含有泛型的方法
    public <M> void method01(M m){
        System.out.println(m);
    }
    //定义一个含有泛型的静态方法
    public static <S> void method02(S s){
        System.out.println(s);
    }
}
测试类:
public static void main(String[] args) {
        //创建对象
        GenericMethod gm1 = new GenericMethod();
        /*
           调用含有泛型的方法method01
           传递什么类型,泛型就是什么类型
         */
        gm1.method01(10);
        gm1.method01(true);
        gm1.method01(8.8);
        gm1.method01("abc");
        gm1.method02("静态方法,不建议创建对象调用,没有必要");
        //推荐直接使用类名去调用静态方法
        GenericMethod.method02("静态方法没有创建对象调用");
        GenericMethod.method02(1);
    }

1.5 定义和使用具有泛型的接口

格式: 修饰符 interface 接口名{

修饰符 <泛型> 返回值类型 方法名(参数列表)

}

代码:

定义含有泛型的接口
public interface GenericInterface<I>{
    void method(I i);
}
接口实现类1:定义类时确定泛型的类型
public class GenericInterfaceImpl1<String> implements GenericInterface<String>{

    @Override
    public void method(String s) {
        System.out.println(s);
    }
}
接口实现类2:在声明的时候不确定泛型的类型,创建对象的时候,再确定泛型的类型
public class GenericInterfaceImpl2<I> implements GenericInterface<I>{
    @Override
    public void method(I i) {
        System.out.println(i);
    }
}
测试类:
    public static void main(String[] args) {
        //创建对象GenericInterfaceImpl1对象
        GenericInterfaceImpl1 gi1 =  new GenericInterfaceImpl1();
        gi1.method("字符串");
        //创建声明时没有确定泛型的实现类对象 再创建对象的时候确定泛型
        GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>();
        gi2.method(10);
        GenericInterfaceImpl2<Double> gi3 = new GenericInterfaceImpl2<>();
        gi3.method(8.8888888);
    }

1.6泛型的通配符

当使用泛型类或者接口的时候,传递的数据中,泛型类型不确定,可以通过通配符表示。但是一旦使用泛型的通配符后,只能使用object类中的共性方法,集合中元素自身方法无法使用。

1.6.1 通配符的基本使用

泛型 通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符,此时只能接收数据,不能往集合中存储数据。

代码:

public static void main(String[] args) {
        Collection<Integer> list1 = new ArrayList<>();
        getElemet(list1);
        Collection<String> list2 = new ArrayList<>();
        getElemet(list2);
    }
//带有通配符的方法
public static void getElemet(Collection<?> coll){}

注意:

1.泛型不存在继承关系,Collection list = new ArrayList();这种写法是错误的

2.通配符不能创建对象使用,只能作为方法的参数使用。ArrayList list = new ArrayList();也是错误的

1.7 通配符的高级使用----受限泛型(了解)

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置,但是在java中的泛型可以指定一个泛型的上限和下限

泛型的上限:

格式: 类型名称 <? extends 类> 对象名称 意义: 只能接受该类型及其子类

泛型的下限:

格式: 类型名称 <? super 类> 对象名称 意义: 只能接受该类及其父类型

例如:

类与类之间的继承关系:Integer extends Number extends Object,String extends object

定义泛型的上限:

//定义泛型的上限 此时的泛型必须是number类或者number类型的子类 public static void getElement01(Collection<? extends Number> coll){}

定义泛型的下限:

//定义泛型的下限 此时的泛型必须是number类或者number类型的父类 public static void getElement02(Collection<? super Number> coll){}

测试类:

    public static void main(String[] args) {
        Collection<Integer> list1 = new ArrayList<>();
        Collection<String> list2 = new ArrayList<>();
        Collection<Number> list3 = new ArrayList<>();
        Collection<Object> list4 = new ArrayList<>();
        
        getElement01(list1);
        //getElement01(list2);
        getElement01(list3);
        //getElement01(list4);
        
        //getElement02(list1);
        //getElement02(list2);
        getElement02(list3);
        getElement02(list4);
    }

因为作者现在也是在学习的小白,这是跟随老师的笔记的总结,如果不对,请告诉我!!!(老师应该不会告我侵权吧)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值