美文网首页
java基础系列05--集合(1)

java基础系列05--集合(1)

作者: addin_gao | 来源:发表于2019-01-14 09:37 被阅读9次

    JAVA 集合

    集合由来:

    数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少

    数组和集合的区别:

    区别1 :

    • 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值

    • 集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象

    区别2:

    • 数组长度是固定的,不能自动增长
    • 集合的长度的是可变的,可以根据元素的增加而增长

    Collection集合

    集合.png
    * boolean add(E e)
    * boolean remove(Object o)
    * void clear()
    * boolean contains(Object o)
    * boolean isEmpty()
    * int size()
        
    public static void main(String[] args){
            Collection c1 = new ArrayList();  // Collection是接口,父类引用指向子类对象
            boolean b1 = c1.add("abc");     // true
            boolean b2 = c1.add(new Person());   // true
            c1.add(true);  // true  添加任何都能返回true
            System.out.println(c1); //ArrayList 父类重写了toString方法 [abc, com.test.Person@15db9742, true]
            System.out.println(c1.remove("abc")); //true 删除成功返回true,否则为false
            System.out.println(c1.contains("a"));// false 
            System.out.println(c1.size()); //2 集合中元素个数
            
    }
    

    集合转数组并且进行遍历(了解):

    public class Student {
        public static void main(String[] args){
            Collection c = new ArrayList();
            c.add("a");
            c.add("b");
            c.add("c");
            c.add("d");
            Object[] arr = c.toArray();
            for(int i=0;i<arr.length;i++){
                System.out.println(arr[i]); // a b c d
            }
            c.clear();
            c.add(new Person("张三",12));
            c.add(new Person("李四",13));
            c.add(new Person("王五",14));
            c.add(new Person("赵六",15));
            Object[] arr1 = c.toArray();
            for(int i =0;i<arr1.length;i++){
    //          System.out.println(arr1[i].getName()); //此时arri[i] 的类型提升到了Object,要调用对象特有的方法需要向下转型
                Person p = (Person)arr1[i];  // 需要向下转型
                System.out.println(p.getName()+"----"+p.getAge());  // 张三----12   李四----13   王五----14   赵六----15
            }
        }
        
    }
    

    Collection集合的带All的方法:

    boolean addAll(Collection c) // c1.addAll(c) 将集合c中的每个元素添加到C1
    boolean removeAll(Collection c) // c1.removeAll(c) 删除c1中含有的c元素,删除交集 
    boolean containsAll(Collection c) //c1.containsAll(c) c1是否包含c,和顺序有关
    boolean retainAll(Collection c) // c1.retainAll(c) c1保留和c的交集,其余删除,调用的集合改变则返回true,不变则返回false
    

    集合的遍历之迭代器遍历:

    Collection c = new ArrayList();
    c.add("a");
    c.add("b");
    c.add("c");
    c.add("d");
    Iterator it = c.iterator(); //获取迭代器
    while(it.hasNext()){ // 若有元素,则返回true,没有返回false
        System.out.println(it.next()); // a b c d
    }
    

    List 集合特有功能

    * boolean add(E element) // 添加元素
    * void add(int index,E element)//根据索引添加元素
    * E remove(int index)  //根据索引移除元素
    * E get(int index)  //根据索引获取元素,可以遍历List集合
    * E set(int index,E element) // 修改指定位置的元素
    

    并发修改异常的解决方法 (ListIterator):

    public static void main(String[] args){
            List c = new ArrayList();
            c.add("a");
            c.add("b");
            c.add("c");
            c.add("d");
    //      Iterator its = c.iterator(); //获取迭代器
    //      while(its.hasNext()){
    //          if( its.next() == "c"){
    //              c.add("xx"); //报错 java.util.ConcurrentModificationException
    //          }
    //      }
            ListIterator it = c.listIterator(); // 获取迭代器(list集合特有的)
            while(it.hasNext()){
                if(it.next() == "c"){
                    it.add("xx");
                }
            }
            System.out.println(c); // [a, b, c, xx, d]
            
    }
    

    List的三个子类的特点:

    ArrayList:
    ​ 底层数据结构是数组,查询快,增删慢。
    ​ 线程不安全,效率高。

    Vector:
    ​ 底层数据结构是数组,查询快,增删慢。
    ​ 线程安全,效率低。

    Vector相对ArrayList查询慢(线程安全的)
    Vector相对LinkedList增删慢(数组结构)
    LinkedList:
    ​ 底层数据结构是链表,查询慢,增删快。
    ​ 线程不安全,效率高。

    查询多用ArrayList

    增删多用LinkedList

    Vector集合(被替代掉了,面试用)

    vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。

    Vector v = new Vector();
    v.addElement("a");
    v.add("b");
    ListIterator its = v.listIterator();
    while(its.hasNext()){
        System.out.println(its.next());
    }
    System.out.println(v);
    

    ArrayList

    public static void main(String[] args){
        // 去除ArraryList的重复项
        ArrayList a = new ArrayList();
        a.add("a");
        a.add("b");
        a.add("b");
        a = getSingleList(a);
        System.out.println(a); //[a, b]
    }
    public static ArrayList getSingleList(ArrayList arr){
        Iterator i = arr.iterator();
        ArrayList a = new ArrayList();
        while(i.hasNext()){
            Object temp = i.next();
            if (!a.contains(temp)){ // 若集合中保存的是自定义对象则自定义对象需要重写equals方法
                a.add(temp);
            }
        }
        return a;
    }
    

    LinkedList的特有功能:

    public static void main(String[] args){
            LinkedList l = new LinkedList();
            l.addFirst("a"); // a
            l.addFirst("b"); // b a
            l.addLast("c"); //  bac
            l.add("d");   //bacd
            Object first = l.getFirst(); // b
            Object last = l.getLast(); // d
            l.removeFirst();  //delete the "b"
            l.removeLast(); // delete the "d" 
            Object s = l.get(1);  // 根据索引获取对应的元素,
            System.out.println(l); // [a,c]
            System.out.println(s); // c
    
    }
    

    泛型:

    限定某个集合的存储元素类型,提高安全性(将运行期的错误转换到编译期) ,省去强转的麻烦

    规定:<>中放的必须是引用数据类型前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)

    //ArrayList<Person> arr1 = new ArrayList<>();  后面的泛型可以省略不写(1.7的新特性菱形泛型)
    //ArrayList<int> arr2 = new ArrayList<Person>(); 错误,泛型限定一定要是引用数据类型,可以写Integer
    //ArrayList<Object> arr3 = new ArrayList<Person>();  报错,前后泛型不一致,而且泛型定义成Object无意义
    ArrayList<Person> arr = new ArrayList<Person>();
    arr.add(new Person("张三",11));
    arr.add(new Person("李四",13));
            
    Iterator<Person> i = arr.iterator(); // 使用泛型限定元素类型
    while (i.hasNext()){
        Person p = i.next();
        System.out.println(p.getAge()+"----"+p.getName());
    }
    
    

    给自己的类加泛型

    class Tool<E>{
        private E e;
        public E getObj(){
            return e;
        }
        public void setObj(E e){
            this.e = e;
        }
        public<T>void show(T t){  // 方法泛型需要与类的一直,如果不一致,则需要在方法上声明泛型
            System.out.println(t);
        }
        public static<W> void shows(W e){ // E是在创建对象的时候才赋值,但是静态则是不用创建对象就能直接调用的
           // 所以静态方法必须要给出自己的泛型
            System.out.println(W); // 可以写E,这里写E的话和类的E就是不同的变量,只是名字相同
        }
    }
    

    泛型接口:

    interface Inter<T>{
        public void show (T t);
    }
    class Demo implements Inter<String>{
    
        @Override
        public void show(String t) {
            System.out.println(t);
        }   
    }
    

    泛型高级之通配符(了解):

    List<?> list = new ArrayList<String>();

    增强for 循环遍历数组和集合

    增强for 循环底层依赖的是迭代器

    public static void main(String[] args){
           // 增强 for循环遍历数组
            int[] arr = new int[]{11,22,33,44};
            for (int i : arr) {
                System.out.println(i); //11 22 33 44 
            }
            // 增强 for循环遍历集合
            ArrayList<String> list = new ArrayList<>();
            list.add("aa");
            list.add("bb");
            list.add("cc");
            list.add("dd");
            for (String string : list) {
                System.out.println(string);  // aa bb cc dd
            }   
    }
    

    三种在遍历的时候删除集合元素:

            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("b");
            list.add("c");
    //      -------第一种删除方式-------------
    //      for (int i = 0; i < list.size(); i++) {
    //          if ("b".equals(list.get(i))){
    //              list.remove(i);
    //              i--; // 需要加这句,才能删除2个b,不加只能删除一个
    //          }
    //      }
            
    //      -------第二种删除方法-------------
            Iterator<String> it = list.iterator();
            while(it.hasNext()){
                if ("b".equals(it.next())){
                    it.remove(); // 不能使用集合的删除,只能使用迭代器的删除,否则并发修改异常
                }
            }
    //      -------第三中删除方法( 不行并发修改异常)--------
    //      for (String string : list) {
    //          if ("b".equals(string)){
    //              list.remove("b");
    //          }
    //      }
    

    JDK1.5的可变参数:

    如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

        public static void main(String[] args){
            int[] arr = new int[]{1,2,3,4};
            print(arr);  // 结果都一样
            print(1,2,3,4);
        }
        public static void print(int... arr){
            // 可变参数,这里的 arr就是一个数组
            for (int i : arr) {
                System.out.println(i);
            }
        }
    

    Arrays工具类的asList()方法的使用

    public static void main(String[] args){
            Integer[] arr = {11,22,33,44};
            // 将数组看作集合去使用,但是不能使用集合的增加和删除方法,其他的方法可以使用
            List<Integer> list = Arrays.asList(arr);
            //list.add(55); // 编译不报错,但是增加和删除会报错,不能操作
            //list.remove(1);// 编译不报错,但是增加和删除会报错,不能操作其余方法可以
            System.out.println(list.get(1)); // 22 
    }
    
    // 集合转为数组
    public static void main(String[] args){
           ArrayList<String> arr = new ArrayList<String>();
           arr.add("a");
           arr.add("b");
           arr.add("c");
           String[] arrs = arr.toArray(new String[0]);
           for (String string : arr) {
             System.out.println(string); 
           }
    }
    

    相关文章

      网友评论

          本文标题:java基础系列05--集合(1)

          本文链接:https://www.haomeiwen.com/subject/uixskqtx.html