SentralLiu

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1.集合的概念
概念:对象的容器,集合中提供了常用的方法,可以实现与数组类似的存储

与数组的区别:
数组长度固定,集合是动态存储的
数组可以存基本类型和引用类型,集合只能存引用类型

集合框架介绍:

 

1.1 Collection接口

//Collection: 集合的根接口
//包含了两个子接口: 1. List   2.Set
//Collection的常用方法:
public class Test1 {
    public static void main(String[] args) {
        Collection co = new ArrayList();
        co.add(1);  //添加元素   Integer-自动装箱
        co.add(3);  //集合只能存对象?
        co.add(2.5);    //Double
        System.out.println(co.contains(1));  //true
        System.out.println(co.remove(1));    //删除单个对象
        
        System.out.println(co.size());  //求长度
        
        Collection co2 = new ArrayList();
        co2.add(5);  
        co2.add(7);
        System.out.println(co.addAll(co2));  //添加一个集合
        
        System.out.println(co);
        /*
        co.clear();
        System.out.println(co.isEmpty());  //true
        System.out.println(co);  //[]  不是null
        */
        
        Object[] as = co.toArray();   //转数组
        System.out.println(Arrays.toString(as));
        
    }
}

1.2. List接口
List接口,是Collection的子接口
包含了两个重要的实现类: ArrayList,LinkedList其中还有一个不太常用实现类Vector
List的特点:存储的元素有序(有序!=排序),可重复

public class Test1 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(1);
        list.add(3);
        list.add(2);
        list.add(3);
        list.add(2, 6);
        System.out.println(list); //1,3,6,2,3
        System.out.println(list.get(2));  //根据下标获取元素
        
        //循环遍历
        for(int i=0;i<list.size();i++) {
            System.out.print(list.get(i)+"\t");  //获取循环遍历的元素
        }
        System.out.println();
        
        //增强for
        for(Object o :list) { //将集合的元素,挨个取出来
            System.out.print(o+"\t");
        }
        System.out.println();
        
        //迭代器:
        Iterator it = list.iterator();
        while(it.hasNext()) { //循环判断是否有下一个
            System.out.println(it.next()); //取出来后,指向下一个
        }
        
    }
}

1.3. Vector实现类

Vector与ArrayList的区别
Vector是加了锁,安全,性能低
ArrayList没有加锁,不安全,性能高(重点)

Vector提供了一些自身独有的方法:

public class VectorTest {
    public static void main(String[] args) {
        Vector vector = new Vector();
        /*
        vector.add(1);
        vector.add(3);
        vector.add(2);
        vector.add(3);
        System.out.println(vector);
        */
        
        //vector独有的方法
        vector.addElement(1);
        vector.addElement(3);
        vector.addElement(2);
        
        System.out.println(vector);
        //循环遍历与ArrayList类似,有基本for,有迭代器,还有自身独有的遍历
        Enumeration enu = vector.elements();  //通过枚举器遍历
        while(enu.hasMoreElements()) { //判断是否有元素
            System.out.println(enu.nextElement());  //如果有则取出来,指向下一个
        }
    }
}

1.4. ArrayList实现类

LinkedList的操作:
    与ArrayList的操作完全一致,只是存储原理不同
ArrayList的存储原理:通过数组扩容的方式存储
分析方式:
1.画图分析原理     2.分析源码(找主线)

LinkedList的存储原理:通过双向链表存储
分析方式:
1.画图分析原理     2.分析源码(找主线)

public class ArrayListTest {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(1);
        list.add(3);
        list.add(1);
        list.add(2);
        System.out.println(list);
    }
}

=====================ArrayList存储原理分析======================

ArrayList源码分析:

list.add(1)方法实现:

1、扩容空间  2、在扩容空间中存元素

ensureCapacityInternal(size + 1); 方法实现:

当第一次存值,则扩容10个空间

grow(minCapacity);具体实现:

数组空间不够,则进行里面的扩容实现

 elementData = Arrays.copyOf(elementData, newCapacity);

 


=====================LinkedList存储原理分析======================

Linked List源码分析(找主线)
    

    final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;

 

==================ArrayList与LinkedList性能PK===================
分析增删改查:
1. 向后追加:相差不大,ArrayList稍快
2. 指定位置的删除和添加  
   ArrayList集体搬迁 PK LinkedList定位==》LinkedList稍快, 
   如果连续指定位置增删,LinkedList快很多
3. 修改和查找
   ArrayList快

结论:后续项目中,经常使用ArrayList,因为常用的操作是定位和向后追加 

public class ArrayListTest2 {
    public static void main(String[] args) {
        List list = new LinkedList();
        long start = System.currentTimeMillis();
        for(int i=0;i<10000;i++) {
            list.add(i);
        }
        System.out.println(System.currentTimeMillis()-start);
    }
}

2. 泛型2.1 泛型应用
案例: 通过List存储自定义对象

class Person{
    String name;
    
    public Person(String name) {
        this.name = name;
    }

    
}
public class Test1 {
    public static void main(String[] args) {
        //问题1:警告太多,清理黄线  2.假设存其他引用类型,编译是通过的,运行时报错
        //报错提示:类型转换异常
        //解决方案:从源头上规避问题,存值前约束所存储的类型为Person类型--泛型
        List<Person> list = new ArrayList<>();
        list.add(new Person("凤姐"));
        list.add(new Person("芙蓉"));
        list.add(new Person("刘亦菲"));
        //list.add("高圆圆");  //从源头上规避了其他类型的值的存储
        
        //循环遍历,获取对象的属性
        Iterator<Person> it = list.iterator();
        while(it.hasNext()) {
            //ClassCastException: String cannot be cast to Person
            Person person = it.next(); //有了泛型约束,无需强转
            System.out.println(person.name);
        }
    }
}


2.2 泛型定义
概述: 参数化类型,把类型作为参数传递,约束了所存储值的类型

常见的泛型分类:泛型类(常用)      泛型接口(常用)       泛型方法
语法: <T>

//泛型类:  MyFan <T>: 约束泛型类中所有使用泛型参数的方法所传的类型
class MyFan <T>{
    public void add(T t) {
        System.out.println(t);
    }
}

//泛型接口:FanInter<T>:约束泛型中接口传递类型,泛型接口实现类也需要定义泛型
interface FanInter<T>{
    void test(T t);
}
//实现类实现泛型接口
class MyImpl<T> implements FanInter<T>{

    @Override
    public void test(T t) {
        
    }
    
    //泛型方法,泛型的约束只能用在该方法中(不常用)
    public <E> void show(E e) {
        System.out.println("泛型方法:"+e);
    }
    
}

public class Test2 {
    public static void main(String[] args) {
        MyFan<Integer> fan = new MyFan();
        fan.add(6);
    }
}


2.3 自定义泛型集合
自定义泛型集合:  泛型接口与实现类组合使用
泛型好处: 规范化所使用的类型    获取本身类型是无需强转,提高安全性
 

interface MyList<E>{  //泛型接口
    public void add(E e);
}

class MyArrayList<E> implements MyList<E>{

    @Override
    public void add(E e) {
        System.out.println("集合存储:"+e);
    }
    
}

public class Test3 {
    public static void main(String[] args) {
        MyList<Integer> list = new MyArrayList<>();
        list.add(666);
    }
}

posted on 2021-10-28 20:03  SentralLiu  阅读(33)  评论(0)    收藏  举报