Java集合基本基本使用

分类

Java集合可以大致分为集合和映射两大类:

集合(Collection)——一个独立元素的序列,其中的元素都遵循某些规则,集合又可以向下细分为:

列表(List)必须以插入的顺序保存元素;
集合(Set) 不能包含重复的元素;
队列(Queue)只能按照队列的形式添加和取出元素(先进先出)。

映射(Map)——一组成对的键值对对象,允许通过键值(Key)来查找值(Value)

数组列表(ArrayList)虽然只是存了值,但是可以通过数值来查找对象,因此可以看作把数字和对象关联在了一起;
映射(Map)允许使用一个对象来查找另一个对象,它把对象和对象关联到一起,称作字典(Dictionary),我们可以使用一个键对象来查找值对象,就像在通过拼音或者笔画来查字典一样。

根据Jdk1.8帮助文档的描述,我们可以把一些常用的集合类分类,如下图:


集合.png

其中右上角加*号的为接口,为了区别于java.awt.List,我们在List前边加了util。

其中的每个类都实现了它们的接口和它们接口的父接口的方法(有点绕,实际上实现一个子接口就意味着必须把它的父接口的方法也实现了),也就是说,我们从最上边的的父接口的方法开始,逐级向下了解,就能更清晰的掌握这些集合的使用。

接下来,就来简单的介绍下Collection和Map的用法。

Collection

我们先来看看Collection都有哪些常用的方法:

添加:

  • boolean add(E e) 添加元素成功返回True

  • boolean addAll(Collection<? extends E> c)将自定集合的所有元素添加到此集合中。

    ps:参数Collection<? extends E> c所有实现Collection的类。

查询:

  • boolean contains(Object o) 此集合包含此元素,则返回True。

  • boolean containsAll(Collection<?> c) 此集合包含指定集合的所有元素则返回True

  • boolean isEmpty() 此结合不包含元素(为空)则返回True

  • int size() 返回集合中的元素数

  • Object[] toArray() 返回包含所有元素的数组

删除:

  • void clean() 删除集合中的所有元素

  • boolean remove(Object o) 根据内容移除指定元素
    题外话:虽然队列(Queue)和栈(Stack)都实现了这个方法,但是因为这个方法违背了它们本身应该有的性质,所以都不推荐使用(实测可行,但是文档里没把这个方法列出来)

  • boolean removeAll(Collection<?> c)移除指定集合中包含的所有元素

  • retainAll(Collection<?> c)与上面是正好相反的,保留指定集合中的所有元素(其他移除)

示例:

接口Collection中拥有这些方法,这也就说明后边的实现类ArrayList、HashSet等等都可以使用这些方法。事不宜迟,赶紧试试~

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;

public class ColletionTest {
    public static void main(String[] args) {
        // 因为只需要测试Collection的函数,所以这里使用向上转型
        Collection<Integer> c1 = new ArrayList();
        Collection<Integer> c2 = new LinkedList();
        System.out.println("刚创建的c1时否为空? " + c1.isEmpty());
        c1.add(1);c1.add(2);c1.add(3);
        c2.add(1);c2.add(2);
        System.out.println("c1的元素:" + c1);
        System.out.println("c2的元素:" + c2);
        System.out.println("c1的长度? " + c1.size());
        Object[] o1 = c1.toArray();//转为数组
        System.out.println("输出数组的第二个元素:"+(Integer)o1[1]);
        System.out.println("c1是否包含2? " + c1.contains(2));
        System.out.println("c1是否包含c2中所有元素? " + c1.containsAll(c2));
        c1.remove(3);// 这里3会自动装包为Integer
        System.out.println("c1的remove(3)d后的元素:" + c1);
        System.out.println("c1是否和c2是否相同? " + c1.equals(c2));//有坑
        System.out.println("clear()前c1是否为空? " + c1.isEmpty());
        c1.clear();
        System.out.println("clear()后c1是否为空? " + c1.isEmpty());
    }
}

输出结果:

刚创建的c1时否为空? true
c1的元素:[1, 2, 3]
c2的元素:[1, 2]
c1的长度? 3
输出数组的第二个元素:2
c1是否包含2? true
c1是否包含c2中所有元素? true
c1的remove(3)d后的元素:[1, 2]
c1是否和c2是否相同? true
clear()前c1是否为空? false
clear()后c1是否为空? true


这里使用了List接口的ArrayList实现类和Queue接口的LinkedList实现类向上转型,但是不是所有Collection的子接口的实现类都能向上转型为Collection如抽象队列(AbstractQueue)。

还有一个坑就是equals方法,如果使用不同的实现类向上转型,equals的比对结果是不可信的,使用containsAll()来比对可能比较安全:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

public class EqualsTest {
    public static void main(String[] args) {
        Collection<Integer> c1 = new ArrayList();
        Collection<Integer> c2 = new HashSet();
        c1.add(1);c1.add(2);
        c2.add(1);c2.add(2);
        System.out.println("equals的比对结果"+c1.equals(c2));
        System.out.println("优化后的比对结果"+(c1.containsAll(c2)&&c2.containsAll(c1)));
    }
}

输出结果:

equals的比对结果false
优化后的比对结果true

关于Collection下List、Map、Stack、Queue的详情【坑】

Map

接下来我们要看看Map中常用的方法:

添加:

  • V put(K key, V value)将指定的键和指定的值相关联

  • void putAll(Map<? extends K,? extends V> m)将此Map的所有映射复制到指定的Map

查询:

  • boolean containsKey(Object key)此Map包含指定的键值,则返回True

  • boolean containsValue(Object value)如果此Map保函映射到指定值的键值,返回True

  • Set<Map.Entry<K,V>> entrySet()返回Map的Set视图

  • Set<K> keySet()返回Key的Set视图

  • Collection<V> values()返回值的Collection视图

  • boolean isEmpty()Map为空返回True

删除:

  • void clear()清除Map中的所有映射

  • V remove(Object key) 删除指定键的映射

  • default boolean remove(Object key, Object value)删除指定键值对的映射

修改:

  • replace(K kay, V oldValue, V newValue)替换指定键指向的值

现在我们可以来练练手了:

import java.util.HashMap;
import java.util.Map;

public class MapTest {
    public static void main(String[] args) {
        Map<Integer,String> m = new HashMap<>();
        m.put(1,"Jack");
        m.put(1,"Tom");
        m.put(2,"Lucy");
        m.put(3,"Lily");
        System.out.println("Map视图:"+m.entrySet());
        System.out.println("Key视图:"+m.keySet());
        System.out.println("Value视图:"+m.values());
        m.remove(1);        
        System.out.println("执行remove(1)后:"+m.entrySet());
        m.replace(2, "nameless");
        System.out.println("替换键为2的映射后:"+m.entrySet());
        System.out.println("执行clear()前Map是否为空:"+m.isEmpty());
        m.clear();
        System.out.println("在执行clear后:"+m.entrySet());
        System.out.println("执行clear()之后Map是否为空:"+m.isEmpty());
    }
}

输出结果:

Map视图:[1=Tom, 2=Lucy, 3=Lily]
Key视图:[1, 2, 3]
Value视图:[Tom, Lucy, Lily]
执行remove(1)后:[2=Lucy, 3=Lily]
替换键为2的映射后:[2=nameless, 3=Lily]
执行clear()前Map是否为空:false
在执行clear后:[]
执行clear()之后Map是否为空:true

可以注意到我们最先添加的Jack被后来的Tom给替代掉了,Map里是不允许一个键对应多个键值的,要想实现这个效果,可以将键值设计为List(其实甚至可以设置为Map)

package mapTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ListTest {

    public static void main(String[] args) {
        Map<Integer,List<String>> m = new HashMap<>();
        List<String> l = new ArrayList<>();
        l.add("Jack");l.add("Tom");
        m.put(1,l);
        System.out.println(m.entrySet());
    }
}

有关Map实现类的详情【坑】

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

推荐阅读更多精彩内容