Java学习日志Day19_集合的高级功能_List子接口_泛型

一、集合的高级功能

  1. 所有带All的功能:
    Collection集合的高级功能:
    boolean addAll(Collection c):添加一个集合中的所有元素
    boolean removeAll(Collection c):删除集合的所有元素
    删除一个元素算是删除还是删除所有算删除?
    删除一个算删除(当前这个元素都包含)
    boolean containsAll(Collection c) :判断是否包含所有元素
    包含一个元素算包含还是包含所有算包含
    包含所有元素才返回true
    boolean retainAll(Collection c):对集合取交集?返回值boolean 什么意思
举例:
public class CollectioDemo {
    public static void main(String[] args) {

        //创建两个集合对象
        Collection c1 = new ArrayList() ;
        //添加元素
        c1.add("abc1") ;
        c1.add("abc2") ;

        c1.add("abc3") ;
        c1.add("abc4") ;
       /* c1.add("abc5") ;
        c1.add("abc6") ;
        c1.add("abc7") ;*/

        Collection c2 = new ArrayList() ;
        //添加元素
        c2.add("abc1") ;
        c2.add("abc2") ;
        c2.add("abc3") ;
        c2.add("abc4") ;
        c2.add("abc1") ;
        c2.add("abc5") ;
        c2.add("abc6") ;
        c2.add("abc7") ;
        System.out.println("c1:"+c1);
        System.out.println("c2:"+c2);

        //boolean addAll(Collection c):添加一个集合中的所有元素
      //  System.out.println(c1.addAll(c2));
       //boolean removeAll(Collection c):删除集合的所有元素
     //   System.out.println(c1.removeAll(c2));

        // boolean containsAll(Collection c)    :判断是否包含所有元素
       // System.out.println(c1.containsAll(c2));

//        boolean retainAll(Collection c):对集合取交集?返回值boolean 什么意思
        System.out.println(c1.retainAll(c2));
        /*
        *   A集合对B集合取交集,交集的元素保存在A集合中,返回值的结果判断A集合的元素是否有变化
        * 有变化,就返回true
        * 没有变化,就返回false!
        *
        * */

        System.out.println("--------------------------");
        System.out.println("c1:"+c1);
        System.out.println("c2:"+c2);
    }
}
  1. Collection获取功能:
    集合的专有迭代器:Iterator iterator() :Collection接口的迭代器
    迭代器属于集合的专有遍历方式
    Iterator:接口
    Object next()返回迭代的下一个元素。
    boolean hasNext():判断迭代器中是否存在下一个元素
迭代器
interface Iterator{

    boolean hasNext() ;
    E next()  ; //E :Element :代表任意类型 (Object)
}

<E>Element,<T> Type 存储元素类型
<K,V>:Key 键,Value值

interface Iterable{
    Iterator iterator():将指定类型的元素在迭代器上进行遍历
}

interface Collection extends Iterable{
     Iterator iterator():将指定类型的元素在迭代器上进行遍历
}

interface List extends Collection{
     Iterator iterator():将指定类型的元素在迭代器上进行遍历

}

//具体子实现类
class ArrayList implements List{

        public Iterator<E> iterator() {
                return new Itr();  //创建Itr类对象
        }

        //ArrayList$Itr  :成员内部类
         private class Itr implements Iterator<E>{

             public boolean hasNext() {
                        return cursor != size;
               }

                    @SuppressWarnings("unchecked")//强制压制警告
                    public E next() {
                        checkForComodification();
                        int i = cursor;
                        if (i >= size)
                            throw new NoSuchElementException();
                        Object[] elementData = ArrayList.this.elementData;
                        if (i >= elementData.length)
                            throw new ConcurrentModificationException();
                        cursor = i + 1;
                        return (E) elementData[lastRet = i];
                    }
         }
}

Collection
迭代器的原理:就是实现了Iterator接口的子实现类

    ArrayList:Itr内部类

List----> ListIterator:列表迭代器 接口----> ListItr内部类
举例1public class CollectionDemo {
    public static void main(String[] args) {

        //创建一个Collection对象
        Collection c = new ArrayList() ;

        //添加元素
        c.add("hello") ;
        c.add("world") ;
        c.add("javaee") ;

        //获取Collection集合的迭代器
        //Iterator iterator()
        Iterator it = c.iterator();

        //获取集合中的下个元素
//        Object next()返回迭代的下一个元素。
      /*  Object obj = it.next();
        System.out.println(obj);
        System.out.println(it.next());
        System.out.println(it.next());*/
     //   System.out.println(it.next());//java.util.NoSuchElementException

        //当前集合的元素取完了,迭代器它并没有去判断是否有下一个元素;如果能在获取之前,添加一个判断功能,防止出现的异常
     /*   if(it.hasNext()){
            System.out.println(it.next());
        }
        if(it.hasNext()){
            System.out.println(it.next());
        }
        if(it.hasNext()){
            System.out.println(it.next());
        }
        if(it.hasNext()){
            System.out.println(it.next());
        }*/

        //循环改进:while循环
        while(it.hasNext()){
            Object next = it.next();        //存储的元素 new String("hello")      "hello"
           // System.out.println(next);

            //遍历同时获取子串长度
          //  System.out.println(next+"---"+next.length());
            //向下转型
            String s = (String) next;
            System.out.println(s+"---"+s.length());
        }
    }
}
举例2/*需求:
 * 现在使用Collection存储5个学生,姓名和年龄,使用Collection的迭代器遍历
 */
public class Student {
    private String name ;
    private int age ;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class CollectionDemo2 {
    public static void main(String[] args) {

        //创建Collection集合对象
        Collection c = new ArrayList() ;

        //创建5个学生
        Student s1 = new Student("貂蝉",20) ;
        Student s2 = new Student("王昭君",25) ;
        Student s3 = new Student("杨玉环",22) ;
        Student s4 = new Student("西施",27) ;
        Student s5 = new Student("高圆圆",41) ;

        //添加到集合中
        c.add(s1) ;
        c.add(s2) ;
        c.add(s3) ;
        c.add(s4) ;
        c.add(s5) ;

        //使用迭代器遍历
        Iterator iterator = c.iterator();
        while(iterator.hasNext()){
            Object o = iterator.next();
            //java.lang.ClassCastException :类转换异常
           // String s = (String) o;//com.qf.collection_02.Student cannot be cast to java.lang.String
            //由于必须考虑: 看集合存储的类型是什么类型!
            Student s = (Student)o ;

            System.out.println(s.getName()+"---"+s.getAge());
        }
     /*   for (Object e : c) {
            System.out.println(e);
        }*/
    }
}
举例3/*        需求:
 *        有一个集合,给集合中添加一些字符串元素,如果这个集合中包含 "world"元素,
 *   给集合新添加一个"javaee"元素,遍历集合!
 *
 *
 *   java.util.ConcurrentModificationException:并发修改异常
 *
 *   出现这个异常:   使用Iterator迭代器去遍历元素,不能使用集合操作元素
 *
 *   解决方案:
 *          1)要么就是集合遍历,集合添加
 *          2)要么迭代器去遍历元素,迭代器去添加元素
 */
public class CollectionDemo3 {
    public static void main(String[] args) {

        //创建一个集合对象
        //Collection c = new ArrayList() ;
        List list = new ArrayList() ;
        //假设添加一些字符串元素
        /*c.add("hello") ;
        c.add("world") ;
        c.add("android") ;*/
        list.add("hello") ;
        list.add("world") ;
        list.add("android") ;

        //遍历:使用Iterator iterator
        //Iterator it = c.iterator();
      //  ListIterator lit = list.listIterator() ;
      /*  while(it.hasNext()){
            Object obj = it.next();
            String s = (String) obj;
            if("world".equals(s)){
                //添加元素
                c.add("javaee") ;
            }
        }*/
       /* while(lit.hasNext()){
            Object obj = lit.next();
            String s = (String) obj;
            if("world".equals(s)){
                //添加元素
                //迭代器添加
                lit.add("javaee") ;
            }
        }

        //遍历集合
     //   Iterator it2 = c.iterator();
        ListIterator lit2 = list.listIterator();
        while(lit2.hasNext()){
            Object obj = lit2.next() ;
            System.out.println(obj);
        }
        */

       //集合遍历,集合添加
       for(int x = 0 ; x < list.size() ; x ++){
           String s = (String) list.get(x);
           if(s.equals("world")){
               list.add("javaee") ;
           }
       }

        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            String s = (String) (iterator.next());
            System.out.println(s);
        }
    }
}

二、List子接口

  1. 添加:
    add(Object e)
    remove()
    contains()

    Object[] toArray()
    Iterator iterator()

  2. List集合特点:
    有序的(存储和取出一致)
    集合的元素是可以重复的

  3. 特有功能
    void add(int index,Object element):在指定的位置处 添加元素
    Object get(int index):通过角标可以获取指定的元素 + size() :普通for循环遍历
    ListIterator listIterator(): 可以使用List集合的专有遍历方式
    Object remove(int index):通过该角标删除指定的元素

  4. List集合遍历方式有几种?
    Object[] toArray()
    Collection的迭代器:Iterator iterator()
    size()+get()相结合

举例:
public class ListDemo {
    public static void main(String[] args) {

        //创建List集合对象
        List<String> list = new ArrayList<String>() ;

        //添加元素
        list.add("hello") ;
        list.add("world") ;
        list.add("world") ;
        list.add("javaee") ;
        list.add("javaee") ;
        System.out.println(list);

        //void add(int index,Object element):在指定的位置处 添加元素
        list.add(2,"android") ;
        System.out.println(list);
        //Object get(int index):通过角标可以获取指定的元素
        String s = list.get(4);
        System.out.println(s);
        System.out.println("--------------------------");
        // Object  remove(int index):通过该角标删除指定的元素
        System.out.println(list.remove(2)); //返回被删除的元素
        System.out.println(list);

        for(int x = 0  ; x < list.size() ; x ++){
            String str = list.get(x);
            System.out.println(str);
        }
    }
}
  1. 那么如果List集合中存储的是Student(自定义对象),遍历同时,去重!
    学生有姓名,年龄
    新建集合思想:
    使用新集合对象判断元素不包含,就不重复!
    contains方法底层依赖于equals方法
    之前:List—底层重写了equals方法,必须他们的是否相同
    现在存储自定义对象,成员信息一致,认为它同是一个人!
    要去重复自定义对象,必须在当前类中重写equals以及 hashCode()
举例:
public class Student {
    private String name ;
    private int age ;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

public class ListTest {
    public static void main(String[] args) {

        List<Student> list = new ArrayList<Student>() ;

        //创建一些学生
        Student s1 = new  Student("高圆圆",41) ;
        Student s2 = new  Student("高圆圆",41) ;
        Student s3 = new  Student("高圆圆",35) ;
        Student s4 = new  Student("文章",30) ;
        Student s5 = new  Student("马宝国",25) ;
        Student s6 = new  Student("王宝强",35) ;
        Student s7 = new  Student("文章",30) ;
        list.add(s1) ;
        list.add(s2) ;
        list.add(s3) ;
        list.add(s4) ;
        list.add(s5) ;
        list.add(s6) ;
        list.add(s7) ;

        //新建一个集合
        List<Student> newList = new ArrayList<Student>() ;
        //遍历以前的集合
        Iterator<Student> it = list.iterator();
        while(it.hasNext()){
            Student student = it.next();
            if(!newList.contains(student)) {
                newList.add(student) ;
            }
        }
        //遍历新集合
        Iterator<Student> it2 = newList.iterator();
        while(it2.hasNext()){
            Student s = it2.next() ;
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}
  1. List集合去重第二种方式:不让你新建集合怎么去重?
    利用选择排序思想
    使用0角标对应的元素和后面的元素进行比较,如果后面的元素重复了,将后面定义干掉,角标–
    而且使用集合元素!
举例:
public class ListTests2 {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>() ;

        list.add("hello") ;
        list.add("hello") ;
        list.add("hello") ;
        list.add("hello") ;
        list.add("world") ;
        list.add("world") ;
        list.add("world") ;
        list.add("world") ;
        list.add("javaee") ;
        list.add("javaee") ;
        list.add("javaee") ;
        list.add("php") ;
        list.add("php") ;
        list.add("php") ;

        //利用选择排序
        for(int x = 0 ; x < list.size()-1 ; x ++){//比较次数
            for(int y = x + 1 ; y< list.size() ; y ++){
                if(list.get(y).equals(list.get(x))){
                    //先删除后面的元素
                    list.remove(y) ;
                    y-- ;

                }
            }
        }

        //迭代器
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String s = iterator.next() ;
            System.out.println(s);
        }
    }
}
举例:
/* 产生1-30 (6个)随机数:Random    将这元素集合中
 */
public class Test {
    public static void main(String[] args) {

        //创建随机数生成器
        Random random = new Random() ;
        //创建一个集合
        ArrayList<Integer> list = new ArrayList<Integer>() ;
        ArrayList<Integer> newList = new ArrayList<Integer>() ;

        for(int x = 0 ;x < 6 ; x ++){
           int num =  random.nextInt(30) +1 ;
           list.add(num) ;
        }

        //元素如何去重
        //遍历list
        //增强for
        /*
            for(存储类型 变量名: 集合对象){

            }
         */
        for(Integer i: list){
            if(!newList.contains(i)){
                newList.add(i) ;
            }
        }
        //新集合遍历
        for(Integer i : newList){
            System.out.println(i);
        }
    }
}
  1. List的三个子实现的特点:
    {11,22,33,44,55}
    1). ArrayList
    List 接口的大小可变数组的实现:底层数据结构是数组
    数组—>查询元素 数组名称[角标]
    查询快,增删慢
    线程角度:
    是一个不安全的类,不同步的,所以默认没有明确要求使用哪种集合都是使用ArrayList(执行效率高)
    2). Vector
    可以实现可增长的对象数组; 底层数据结构数组
    数组—>查询元素 数组名称[角标]
    查询快,增删慢
    线程角度:
    Vector 是同步的,-----线程安全可靠, 执行效率低
    3). LinkedList
    链接列表实现:底层数据结构是链表
    查询慢:都需要从链接列表查到末尾
    增删快:数据域和指针域; 使用中间互换!
    线程角度:
    实现不同步的,是一个线程不安全的类,执行效率高!

三、泛型

  1. 泛型:<集合中存储类型>
    为了让我们集合的元素类型一致,所以Java提供了泛型,
    模拟数组方式,在创建集合对象的时候,就已经明确了类型,防止出现安全问题!
  <E>
          格式:
           集合<存储类型>  对象名  =new  子实现类名<存储类型>() ;
  1. 泛型的好处:
    1)提供程序的安全性,避免了强制类型转换
    2)将运行时期异常提前了编译时期
    3)解决创建集合的黄色警告线问题
  2. 泛型应用范围:---->集合中使用居多! Class:反射中
    泛型可以在接口上,也可以定义在类上,也可以在方法上使用!
举例:
//@SuppressWarnings("all"):jdk内置注解:  压制警告 注解(接口)
public class GenericDemo {
    public static void main(String[] args) {
        //回想我们的数组
        //定义一个字符串数组
       // String[] strArray = {"hello","world","javaEE",100} ;

        Collection<String> c = new ArrayList<String>() ;
        c.add("hello") ;
       // c.add(100) ;
        c.add("world") ;
        c.add("javaee") ;
        System.out.println(c);

        System.out.println("---------------------------");
        //迭代器
        Iterator<String> it = c.iterator();
        while(it.hasNext()){
            String s = it.next() ;
            System.out.println(s+"---"+s.length());
        }
    }
}
  1. 早期没有使用泛型之前,程序不安全
    多态: 向下转型----->出现类型不匹配,存储的类型和接收的类中不一致(ClassCastException)
举例:
public class ObjectTool {
    private Object obj ;

    //定义设置数据的方法
    public void set(Object obj){
        this.obj = obj ;
    }

    //定义一个获取数据的方法
    public Object get(){
        return obj ;
    }
}

public class ObjectToolTest {
    public static void main(String[] args){

        //创建工具类对象
        ObjectTool objectTool = new ObjectTool() ;
        objectTool.set("高圆圆"); //Object obj = new String ("") ;
        //获取它的内容
        String s = (String) objectTool.get();
        System.out.println("姓名是:"+s);
        //java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
        //Integer i = (Integer) objectTool.get();
        //System.out.println(i);
        System.out.println("----------------------");
        ObjectTool ot2 = new ObjectTool() ;
        ot2.set(41); //Object obj = new Integer(41) ;
        //String s2 = (String) ot2.get();//ava.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        //System.out.println(s2);
        Integer i2 = (Integer) ot2.get();
        System.out.println("年龄是:"+i2);
    }
}
  1. 早期没有使用泛型之前,程序不安全
    多态: 向下转型----->出现类型不匹配,存储的类型和接收的类中不一致(ClassCastException)
    现在将泛型定义在类上:
    可以提高程序安全性,避免了强制类型转换,将运行时期异常提前了编译时期
举例:
//改进:将泛型定义在类上

public class ObjectTool<T> {
    private T obj ;
    //定义设置数据的方法
    public void set(T obj){
        this.obj = obj ;
    }

    //定义一个获取数据的方法
    public T get(){
        return obj ;
    }
}

public class ObjectToolTest {
    public static void main(String[] args){
        //创建ObjectTool<>对象:明确了类型
        ObjectTool<String> ot = new ObjectTool<String>() ;

        //ot.set(41) ;
        ot.set("高圆圆");
        //Integer i = ot.get() ;
        String i = ot.get() ;
        System.out.println("姓名是:"+i);
        System.out.println("-------------------");
        ObjectTool<Integer> ot2 = new ObjectTool<Integer>() ;
        ot2.set(41);
        //ot2.set("张佳宁");
        Integer ii = ot2.get();
        System.out.println("年龄是:"+ii);
    }
}
举例:
* 将泛型定义在方法
 */
//public class ObjectTool<T> {
public class ObjectTool {

   /* //定义一些成员方法
    public void show(String s){
        System.out.println(s);
    }
    public void show(boolean b){
        System.out.println(b);
    }
    public void show(double d){
        System.out.println(d);
    }
    public void show(char ch){
        System.out.println(ch);
    }*/

   //优化:将泛型定义类方法上
   public <T> void show(T t){ //提供这个方法的扩展性,形式参数可以是任意的类型:Object
        System.out.println(t);
    }
}

public class ObjectToolTest {
    public static void main(String[] args) {

        //创建ObjectTool
      //  ObjectTool ot = new ObjectTool() ;
     /*   ot.show("hello");
        ot.show('h');
        ot.show(true);
        ot.show(12.56);*/

     /*ObjectTool<String> ot = new ObjectTool<String>() ;
     ot.show("hello");
    ObjectTool<Integer> ot2 = new ObjectTool<Integer>() ;
    ot2.show(100);*/
     /*
     * 之前将泛型定义在类上,方法的形式参数需要和类上的泛型类型保持一致,存在弊端
     * 传递一些数据类型,需要通过类上的泛型来确定(创建对象),麻烦
     * 能不能将泛型定义的方法上呢?
     * */

     ObjectTool ot = new ObjectTool() ;
     ot.show(100);
     ot.show(true);
     ot.show("hello");
     ot.show('A');
    }
}
6. 泛型高级通配符(了解)
<?>  :这个集合可以存储任意的Java数据类型 或者是Object
<? extends E>:向下限定: 当前是E这个类型或者是E类型的子类 (从后往前看符号)
<? super E>:向上限定:跟E这个类类型一致或者是它的父类

举例:
public class CollectionDemo {
    public static void main(String[] args) {

        //创建集合对象
        Collection<?> c1  = new ArrayList<Object>() ;
        Collection<?> c2  = new ArrayList<Animal>() ;
        Collection<?> c3  = new ArrayList<Cat>() ;
        Collection<?> c4  = new ArrayList<Dog>() ;

        System.out.println("--------------------------------") ;
        Collection<? extends  Animal> c5 = new ArrayList<Animal>() ;
        //Collection<? extends  Animal> c6 = new ArrayList<Object>() ;
        Collection<? extends  Animal> c6 = new ArrayList<Cat>() ;
        Collection<? extends  Animal> c7 = new ArrayList<Dog>() ;
        System.out.println("--------------------------------") ;

        Collection<? super Cat> c8 = new ArrayList<Cat>() ;
        Collection<? super Cat> c9 = new ArrayList<Animal>() ;
        Collection<? super Cat> c10 = new ArrayList<Object>() ;
    }
}
class Animal{
}
class Dog extends  Animal{}
class Cat extends Animal{}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

igfff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值