7.Java容器详解

Java里面的容器是核心概念,这个是面向对象区别C语言的主要区别(这个是我个人认为的,当然区别还有很多)


549734-20160920135339059-1268675998.png

基本从学习java的第二天就会接触容器的概念,包括List、Vector(JDK1.5后基本不再用了)、ArrayList、HashMap等等。有了容器,在日常开发中能很容易把业务逻辑融合到容器中,能替代数组的大部分操作。
谈到数组,估计很多人第一印象是多维数组循环是多么的复杂,我当时学C时,二维数组就基本把人搞晕了,不过到Java里面,因为容器的存在,数组一般不会用到,多数都用容器替代,主要原因是数组初始化时需要定义数组长度,而容器则不需要,基本是可变长度。定义一个可变长度的数组还是比较麻烦的。

上面那个图中,其中淡绿色的表示接口,红色的表示我们经常使用的类。

基本概念

Collection
一个独立元素的序列,这些元素都服从一条或多条规则。其中List必须按照插入的顺序保存元素、Set不能有重复的元素、Queue按照排队规则来确定对象的产生顺序(通常也是和插入顺序相同)
Map
一组成对的值键对对象,允许用键来查找值。ArrayList允许我们用数字来查找值,它是将数字和对象联系在一起。而Map允许我们使用一个对象来查找某个对象,它也被称为关联数组。或者叫做字典。

List主要用法
代码参见:com.critc.container.ListTest.java

 public static void main(String[] args) {
        // List基本操作
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        List<Integer> list2 = new ArrayList<>();
        //第一种循环输入方式
        for (String str : list) {
            System.out.println("第一种输出list值:" + str);
        }

        //第二种循环输出方式
        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            System.out.println("第二种输出list值:" + str);
        }

        //第三种循环输出方式
        Iterator it = list.iterator();
        while (it.hasNext()) {
            System.out.println("第三种输出list值:" + it.next());
        }
    //第四种循环输出方式
   list.forEach(str -> System.out.println("JDK8中输出list值:" + str));
    }

List在使用过程中有个陷阱,就是remove方法,平时想从list列表中直接删除一个值,结果循环后发现不对,原理就是每删除一个元素,该list的size值变化了,导致后续的循环错位。
代码参见:com.critc.container.ListRemoveTest

 public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");

       /* for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            list.remove(str);
            System.out.println("剩余元素:" + list.toString());
        }*/

        //从list的最后一个元素进行循环
        for (int i = list.size() - 1; i >= 0; i--) {
            String str = list.get(i);
            list.remove(str);
            System.out.println("剩余元素:" + list.toString());
        }
    }

** 解决这个问题的方式就是list进行倒序循环,保证删除一个元素后整个list的顺序是不变的,这就可以正常解决问题了**

set主要用法

set区别list的主要原因就是set不允许对象重复,list是可以的。
代码参见:com.critc.container.SetTest

 public static void main(String[] args) {
        Set set = new HashSet();
        set.add("abc");
        set.add("cde");
        set.add("efg");
        set.add("fgh");
        set.add("abc"); //重复的abc,set会自动将其去掉
        System.out.println("size=" + set.size());
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println("输出set的值:" + it.next());
        }
    }

queue主要方法

queue这个用的比较少,只允许在表的一端进行插入,而在另一端进行删除元素的线性表,一般用在模拟一个队列,从对头获取并删除(pool()),从队尾加入(offer())。
代码参见:com.critc.container.QueueTest

 public static void main(String[] args) {
        //add()和remove()方法在失败的时候会抛出异常(不推荐)
        Queue<String> queue = new LinkedList<String>();
        //添加元素
        queue.offer("a");
        queue.offer("b");
        queue.offer("c");
        queue.offer("d");
        queue.offer("e");
        for (String q : queue) {
            System.out.println("循环队列:" + q);
        }
        System.out.println("---------------------");
        System.out.println("获取第一个元素并把这个删除:" + queue.poll()); //返回第一个元素,并在队列中删除
        System.out.println("---------------");
        System.out.println("获取第一个元素=" + queue.element()); //返回第一个元素,不移除,使用element()或peek()方法
        for (String q : queue) {
            System.out.println(q);
        }
    }

Map主要方法

Map集合的key具有一个特征:所有的key不能重复,且key之间没有顺序(TreeMap是有顺序的),如果将Map集合的所有key集中起来,那这些key就组成了一个set集合,则map集合提供了keySet()方法返回所有key组成的集合。
代码参见:com.critc.container.HashMapTest

public static void main(String[] args) {
        HashMap<String, Double> scores = new HashMap<>();
        scores.put("语文", 89.0);
        scores.put("数学", 83.0);
        scores.put("英文", 84.0);
        System.out.println(scores.values());
        Set<Map.Entry<String, Double>> entrySet = scores.entrySet();
        for (Map.Entry<String, Double> entry : entrySet) {
            System.out.println("取得key:" + entry.getKey());
            System.out.println("对应的value为:" + entry.getValue());
        }
        System.out.println("是否包含key:"+ scores.containsKey("语文"));
        System.out.println("是否包含value:"+ scores.containsValue(83.0));
    }

Hashmap的主要方法有put(),containsKey().containsValue()
跟map有关的还有LinkedHashMap和TreeMap,这两个是有序的HashMap,具体区别找度娘即可。

java的容器是非常复杂的,这里面还涉及一个线程安全和线程不安全的概念,比如HashMap和HashTable,HashTable是线程安全的,可以在不同线程中通过HashTable来共享对象。普通开发中用HashMap足够,很少会用到HashTable的。我遇到过的用HashTable 的例子是通过HashTable来存储多个数据源对象,在多线程中调用HashTable来获取不同的数据源,一开始是用HashMap,后来发现存在数据源获取错误的时候,最后才发现是线程安全问题。

源码下载

本例子详细源码

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,018评论 11 349
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,050评论 0 8
  • 译者注:技术日新月异,不保证此文章有效性,请以官方更新为准.另外为了便于理解,翻译不会照搬原文而是稍作修改 翻译日...
    时代小召唤阅读 2,218评论 0 0