Java进阶---集合

一、数组和集合的比较

数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。如:

1.数组能存放基本数据类型和对象,而集合类存放的都是对象的引用,而非对象本身!
2.数组容易固定无法动态改变,集合类容量动态改变。
3.数组无法判断其中实际存有多少元素,length只告诉了数组的容量,而集合的size()可以确切知道元素的个数
4.集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式
5.集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可实现各种复杂操作,大大提高了软件的开发效率

二、List集合

有序列表,允许存放重复的元素;
实现类
ArrayList:数组实现,查询快,增删慢,轻量级;(线程不安全)
LinkedList:双向链表实现,增删快,查询慢 (线程不安全)
Vector:数组实现,重量级 (线程安全、使用少)

三、ArrayList

底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。
ArrayList数组线性表的特点为:类似数组的形式进行存储,因此它的随机访问速度极快。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。

四、LinkedList

LinkedList是采用双向循环链表实现的。
利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。
它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等。
经常用在增删操作较多而查询操作很少的情况下:
队列和堆栈。
队列:先进先出的数据结构。
栈:后进先出的数据结构。
注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。

五、集合的遍历--ArrayList

import java.util.*;
 
public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一种遍历方法使用foreach遍历List
     for (String str : list) {            //也可以改写for(int i=0;i<list.size();i++)这种形式
        System.out.println(str);
     }
 
     //第二种遍历,把链表变为数组相关的内容进行遍历
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //这里也可以改写为  foreach(String str:strArray)这种形式
     {
        System.out.println(strArray[i]);
     }
     
    //第三种遍历 使用迭代器进行相关遍历
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判断下一个元素之后有值
     {
         System.out.println(ite.next());
     }
 }
}

三种方法都是用来遍历ArrayList集合,第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度。

六、ArrayList注意点(面试可能会被问到)

a.如果在初始化ArrayList的时候没有指定初始化长度的话,默认的长度为10.

/**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
    this(10);
    }

b.ArrayList在增加新元素的时候如果超过了原始的容量的话,ArrayList扩容ensureCapacity的方案为“原始容量*3/2+1"哦。

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
    newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
}
}

c.ArrayList是线程不安全的,在多线程的情况下不要使用。

    如果一定在多线程使用List的,您可以使用Vector,因为Vector和ArrayList基本一致,区别在于Vector中的绝大部分方法都
    使用了同步关键字修饰,这样在多线程的情况下不会出现并发错误哦,还有就是它们的扩容方案不同,ArrayList是通过原始
    容量*3/2+1,而Vector是允许设置默认的增长长度,Vector的默认扩容方式为原来的2倍。
    切记Vector是ArrayList的多线程的一个替代品。

d.ArrayList实现遍历的几种方法

package com.yonyou.test;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
public class Test{
public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一种遍历方法使用foreach遍历List
     for (String str : list) {            //也可以改写for(int i=0;i<list.size();i++)这种形式
        System.out.println(str);
    }
 
     //第二种遍历,把链表变为数组相关的内容进行遍历
    String[] strArray=new String[list.size()];
    list.toArray(strArray);
    for(int i=0;i<strArray.length;i++) //这里也可以改写为foreach(String str:strArray)这种形式
    {
        System.out.println(strArray[i]);
    }
     
    //第三种遍历 使用迭代器进行相关遍历
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())
     {
         System.out.println(ite.next());
     }
 }
}

集合数组的相关方法

       //collection接口方法
        Collection<String> t1 = new ArrayList();
        //添加元素
        t1.add("Jack");
        t1.add("Merry");
        System.out.println(t1);

        //删除元素
        t1.remove("Jack");
        System.out.println(t1);

        //获取元素个数
        System.out.println(t1.size());

        //判断是否包含一个元素
        if (t1.contains("Merry")){
            System.out.println("有Merry");
        }else {
            System.out.println("没有Merry");
        }

        //判断是否为空
        if (t1.isEmpty()){
            System.out.println("是空的");
        }else {
            System.out.println("不是空的");
        }

        //判断两个集合是否相同
        Collection<String> t2 = new ArrayList();

        t2.add("Merry");
        t2.add("Jack");
        t2.add("tome");
        t2.add("bluck");

        if (t1.equals(t2)){
            System.out.println("相同");
        }else {
            System.out.println("不相同");
        }
        //集合的情空
        System.out.println("------------------");
        //集合的遍历
        /**1.使用Iterator遍历
         * hasNext 判断是否有下一个对象
         * next 获取下一个对象
         * remove 删除当前遍历过后的对象
         */
      
        Iterator iterator = t2.iterator();

        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //错误的方法
        while (iterator.next() != null){
            System.out.println(iterator.next());
        }

        System.out.println("------------------");
        //2.用for-each 增强for循环
        for (String obj: t2){
            System.out.println(obj);
        }
        

        //List接口 extends Collection
        // ArrayList  内部是连续的内存空间 优点:访问方便get(); 缺点:删除,添加比较难
        // LinkedArrayList 内部使用链表实现 (不一定连续) 优点:增加 删除效率高 缺点:访问不方便
        // 集合里面只能存放对象
        // 包装类-->Byte Char Integer Long Float Double Boolean
        // java会自动将基本数据类型包装为对应的类
       
        ArrayList<Integer> score = new ArrayList<>();
        score.add(2);
        score.add(3);
        score.add(0,1);//在指定位置添加
        System.out.println(score);

        //访问元素
        score.get(1);
        System.out.println(score);
        //修改元素 (下标,元素)
        score.set(0,0);
        System.out.println(score);
        //删除元素 指定下标
        score.remove(0);
        System.out.println(score);
        //删除指定的元素
        score.remove((Integer)2);
        System.out.println(score);
        //清空
        score.clear();
        System.out.println(score);

        ArrayList<Integer> a2 = new ArrayList<>();
        a2.add(1);
        a2.add(2);
        a2.add(3);
        a2.add(4);
        a2.add(5);
        //加入元素 把另一个集合中的元素加入
        score.addAll(a2);
        System.out.println(score);
        System.out.println("------------------");

        ArrayList<Integer> a3 = new ArrayList<>();
        a3.add(1);
        a3.add(2);

        score.retainAll(a3);//取交集
        System.out.println(score);

        System.out.println("------------------");
        ArrayList<Integer> a4 = new ArrayList<>();
        a4.add(1);
        a4.add(2);
        a4.add(3);
        a4.add(4);
        a4.add(5);

        System.out.println(a4.indexOf(1));//第一次出现的位置
        System.out.println(a4.lastIndexOf(1));//最后一次出现的位置

        System.out.println("------------------");
        //将ArrayList转化为普通数组
       Integer[] object = new Integer[a4.size()];
       a4.toArray(object);
       System.out.println(object);

        System.out.println("------------------");
        Iterator iterator = a4.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        System.out.println("------------------");

        //获取集合某个范围的子集合
        List<Integer> integerList = a4.subList(1,3);
        System.out.println(integerList);

        System.out.println("------------------");
       
        ArrayList<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);

        //Lambda表达式  删除对2取余结果为0的数
        nums.removeIf( obj -> obj % 2 == 0);

        System.out.println(nums);
       
        // 1.使用方式:定义一个类来实现接口
        ArrayClass ac = new ArrayClass();
        int[] num = {1,2,3,4,5,6};
        PXDClass pc = new PXDClass();
        ac.test(num, pc);
     
        // 2.使用匿名类
        ArrayClass ac = new ArrayClass();
        int[] num = {1,2,3,4,5,6};
        ac.test(num, new Show() {
            @Override
            public void customShow(int element) {
                System.out.println(element);
            }
        });
        

        // 3.使用Lambda表达式
        ArrayClass ac = new ArrayClass();
        int[] num = {1,2,3,4,5,6};
        ac.test(num, (int element) -> {System.out.println(element);});
    }
}

// 闭包  把函数作为一个方法的参数
class ArrayClass{
    public void test(int[] target, Show s){
        for (int element: target){
            s.customShow(element);
        }
    }
}

// 必须是接口 这个接口里面只有一个方法
interface Show{
    void customShow(int element);
}
// 实现Show接口
class PXDClass implements Show{

    @Override
    public void customShow(int element) {
        System.out.println(element);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容

  • 原文地址 Java集合 Java集合框架:是一种工具类,就像是一个容器可以存储任意数量的具有共同属性的对象。 Ja...
    gyl_coder阅读 978评论 0 8
  • ​ 在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处...
    Java帮帮阅读 1,420评论 0 6
  • Java集合类可用于存储数量不等的对象,并可以实现常用的数据结构如栈,队列等,Java集合还可以用于保存具有映射关...
    小徐andorid阅读 1,939评论 0 13
  • 概念 在Java中List有两个,一个是java.util下的接口,另一个是java.awt下的类,这里只讨...
    still_loving阅读 1,310评论 0 1
  • 生活在纷繁的社会,追求身心的健康、幸福不是一件易事,很多时候会觉得疲惫,甚至迷茫。除了受到一些外界客观原因的影...
    鲁伟竹原爱阅读 674评论 0 0