java 集合

集合是对象的容器,实现了对对象的常用的操作,类似数组功能。

和数组的区别:

  • 数组长度固定,集合长度不固定
  • 数组可以存储基本类型和引用类型,集合只能存储引用类型
  • 使用时需要导入类

Collection 接口

Collection 继承 Iterable 接口,实现子类可放多个 object 元素,Collection 接口无直接实现类,是通过子类接口 Set 与 List 实现。

是单列集合的顶层实现接口,他表示一组对象,这些对象也称 Collectioin 的元素。

JDK 不提供此接口的任意直接实现,他提供更具体的子接口(如 Set 和 List)的实现。

List

list 集合是 collection 的子接口,元素有序,且添加顺序与取出顺序一致,支持索引。

List 是一个接口,继承自 Collection 接口。

List 是一个有序集合,用户可以精确的控制列表中的每一个元素的插入位置。可以通过整数索引访问元素,并搜索列表中的元素。

与 Set 集合不同,列表通常允许重复元素。

List 集合特点:

  • 有序
  • 可重复

List 集合的特有方法:

  • add(index,E)指定位置添加元素

  • remove(index)删除指定位置的元素

  • set(index,E)修改指定位置的元素

  • get(index)获取指定位置的元素

  • List 集合的几种常用方法

List<> list = new ArraryList();
list.add(obj)//末尾添加元素
list.add(index,obj)//在指定位置添加元素
list.remove(obj)//删除元素
list.indexof(obj)//返回第一次出现的位置
list.lastIndexOf(obj)//返回最后出现的位置
list.set(indes,obj)//设置指定位置的元素,相当于替换
list.get(index)//返回指定位置的元素
list.contains(obj)//查找当前元素是否存在。
list.size()//返回list的长度
list.clear()//清空集合
list.isEmpty()//判断是否为空
list.removeAll(list)//删除多个元素。

Arraylist

Arrarylist 的底层维护了一个 Object 类型的 elementData 数组,其底层就是一个数组。

ArrayList 集合:可调整大小的数组的实现 List 接口。 实现所有可选列表操作,并允许所有元素,包括 null 。

底层是数组, 查询快,增删慢于 LinkedList 集合

  • 无参构造扩容

    若使用无参构造,初始的 elementData 为 0,第一次添加元素,扩容为 10,若再次扩容,则扩容为 elementData 的 1.5 倍。0->10->15->22....
  • 有参构造扩容

    若使用 new Arrarylist(int n)初始化数组,则为指定大小,扩容时也是按照 elementData 的 1.5 倍

Vector

Vector 是 List 的子类,继承 AbstractList 接口,实现 List 接口,底层也是一个 Object[] elementData 数组。

Vector 是线程同步的,是线程安全的,开发中若需要线程同步,用 Vextor 集合。

LinkedList

Linked 的意思是链接,字面意思来看,该集合是一个链表,事实也正是如此,LinkedList 的底层是实现了双向链表和双端队列。

可以添加任意的重复元素,包括 null。

由于是链表,所以不需要扩容,增删效率高。

//链表实现演示
public class Node {
private Object item;//对象
public Node first;
public Node last; public Node(Object name) {
this.item = name;
}
}

LinkedList 集合特有功能

        LinkedList<String> link = new LinkedList<String>();
link.add("hello");
link.add("world");
link.add("hello world");
//添加元素
link.addFirst("fist");
link.addLast("last");
System.out.println(link);
System.out.println("------------------");
//获取元素
System.out.println(link.getFirst());
System.out.println(link.getLast());
System.out.println("------------------");
//删除元素
link.removeFirst();
link.removeLast();
System.out.println(link);
System.out.println("------------------");

List 的最常用的三种遍历方法

//以ArraryList为例
public static void main(String[] args) {
List list = new ArrayList();
List list = new ArrayList();
list.add("11");
list.add("12");
//普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//增强for
for (Object o : list) {
System.out.println(o.toString());
}
//iterator循环
//通过列表迭代器添加元素,不会出现并发修改异常
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}

实例:将 Student 对象添加到集合,三种方式遍历

        Student student = new Student("张三",18);
Student student2 = new Student("wangjiaqi",13);
ArrayList<Student> array = new ArrayList<Student>();
array.add(student);
array.add(student2);
//增强for
for (Student students : array) {
System.out.println(students.getName()+students.getAge());
}
//迭代器
Iterator<Student> it = array.iterator();
while (it.hasNext()) {
Student students = it.next();
System.out.println(students.getName()+students.getAge());
}
//普通for
for(int i = 0; i < array.size(); i++){
Student students = array.get(i);
System.out.println(students.getName()+students.getAge());
}

Set

Set 接口也是单例的,是无序的,增加和取出顺序是不确定的,无索引不可重复,null 最多有一个。

继承自 Collection 接口,

Set 的方法与 List 的方法相差不大,但不能用索引的方式遍历。

HashSet

HashSet 实现 Set 接口,其底层是 HashMap,由于 HashMap 的底层是数组+链表+红黑树,所以 HashSet 的底层就是数组+链表+红黑树,存储时,底层通过 equles()和 hash()方法来确定存储位置,所以存入与取出的顺序不一致。

HashSet 的初始大小是 16 长度大小的数组,当数组的容量达到 16 的 0.75 倍时,会进行提前扩容,也就是数组在满足 12 时,会进行扩容,其扩容倍数为 2 倍。

注:当数组长度大于 64,同时链表长度大于 8 时,hashSet 变为红黑树存储,优化存储结构。

要注意重写 hashCode 与 equlse 方法才能使不同对象的相同内容实现不重复。

LinkedHashSet

父类是 HashSet,底层是 LinkedHashMap,维护了一个数组+双向链表,也是以 hsash 值来确定位置。存储结构是双向链表,所以是有序的,不允许有双向链表。

  • 扩容机制

    • 第一次时,数组 table 扩容到 16,底层是存储在 LinkedHashMap$Entry 对象节点上,数组是 HashMap$Node[],在数组中存放 LinkedHashMap$Entry 对象。

TreeSet

底层是 TreeMap,可以进行排序,当我们使用无参构造器,创建 TreeSet 时,仍然是无序的.

当我们需要按照某种方式进行排序时,需要使用 TreeSet 提供的一个构造器,可以传入一个比较器[匿名内部类]并指定排序规则

//具体的比较规则还需根据实际进行重写,这里举一个例子。
TreeSet<Object> objects = new TreeSet<>(new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
});

TreeSet 接口间接实现了 Set 接口,是一个有序的集合,它的作用是提供有序的 Set 集合

TreeSet 的特点

  1. 元素有序:按照构造方法进行排序

    1. TreeSet()根据元素的自然排序进行排序
    2. TreeSet(Comparator comparator):根据指定的比较器进行排序,自然排序需要在类中实现 comparator 接口

  2. 没有索引,不能用普通 for 循环遍历

  3. 继承 Set 集合,无重复元素

        TreeSet<Integer> ts = new TreeSet<Integer>();//自然排序
ts.add(10);
ts.add(20);
ts.add(4);
for (Integer i : ts) {
System.out.println(i);//输出4,10,20
}

通过指定比较器进行排序

TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {//o1是o2是的下一个
int num = o1.getAge() - o2.getAge();
int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num;
return num2;
}
});
//创建对象
Student s1 = new Student("maoyaning", 32);
Student s2 = new Student("asdfds", 53);
Student s3 = new Student("khljn", 24);
Student s4 = new Student("sdfwfds",24);
//添加集合元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s : ts) {
System.out.println(s.getName() + " " + s.getAge());
}

Set 两种循环遍历:

由于 Set 集合的底层,所以无法用下标遍历,因此只能用增强 for 和 iterator 进行遍历

  1. 增强 for
for (String str : set) {
System.out.println(str);
}
  1. 迭代器
Set set = new HashSet();
Iterator it = set.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}

Map 接口

Map<K,V>,是一个接口,将键映射到值,不能包含重复的键,每个键只能映射一个值。

Map 接口用于存储具有映射关系的数据,key-value。

底层:

  • 在创建 Map 集合时,Map 的底层会创建 EntrySet 集合,用于存放 Entry 对象,而一个 Entry 对象具有 key 和 value,同时创建 Set 数组指向 key,创建 collection 对象指向 value,取出时,实际上是调用 set 和 collection 数组的地址进行调用,从而提高遍历效率。

在进行 map 元素添加时,map.put()方法在底层上是通过 hashcode 与 equals 方法进行比较,当 key 相同时,会进行替换。

要注意的是,HashSet 的底层也是 HashMap,也是以键值对的形式进行存储的,只不过在进行录入时,把 value 值设置为一个常数,所以在 HashSet 中,不能存储相同的值(会进行覆盖)。

而在 Map 中,可以存储相同的 value 值,但是 Key 不能重复,也就是说在 Map 中,key 可以有 null,但是只能有一个,value 可以有多个 null。

实际开发中,常用 HashMap,TreeMap,LinkedHAshMap,和 HashTable 的子类 properties。

Map 集合的方法

Map<String, String> map = new HashMap<String, String>();
//put方法添加元素
map.put("01","maoyaning");
map.put("02","guojing");
//remove方法删除元素
map.remove("01");
//clear方法移除所有元素
map.clear();
//containsKey方法判断是否包含指定的键
System.out.println(map.containsKey("01"));
//containsValue方法判断是否含有指定的值
System.out.println(map.containsValue("maoyaning"));
//size返回集合的键值对个数
System.out.println(map.size());
//isEmpty判断集合是否为空
System.out.println(map.isEmpty());

Map 集合的获取功能

Map<String, String> map = new HashMap<String, String>();
map.put("zhangwuji","01");
map.put("asdf","dsf");
//get方法,根据键,返回值单个值
System.out.println(map.get("zhangwuji"));
//keySet获取所有键的集合
Set<String> keySet = map.keySet();//获取key的Set集合
//增强for循环迭代获取key值
for (String key : keySet) {
System.out.println(map.get(key));
}
//values获取所有值的集合
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
/**在创建 Map 集合时,
Map 的底层会创建 EntrySet 集合,
用于存放 Entry 对象,
而一个 Entry 对象具有 key 和 value,
同时创建 Set 数组指向 key,
创建 collection 对象指向 value,
取出时,实际上是调用 set 和 collection 数组的地址进行调用,
从而提高遍历效率。*/

Map 集合的遍历

//方法一
Map<String, String> map = new HashMap<String, String>();
map.put("01","mao");
map.put("02","ya");
//Map集合的遍历方法
//获取所有键的集合,用KeySet方法实现
Set<String> set = map.keySet();
//遍历每一个键
for (String key : set) {
//根据键找到值
String value = map.get(key);
System.out.println(value);
}
//方法二
//通过entryset方法获得键值对集合
//获取所有键值对对象的集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//遍历键值对对象集合,得到每一个键值对对象
for (Map.Entry<String, String> entry : entries) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
} //方法三
Set<Map.Entry<String, String>> entries = map.entrySet();
Iterator<Map.Entry<String, String> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
System.out.println(next.getKey()+next.getValue()); }

java 入土--集合详解的更多相关文章

  1. java常用集合详解 contains

    java集合是对常用数据集合的封装,差不多就是数组吧,验证某个元素是否在数据集合里,最原始的方法是,用个循环,"某个元素"与数据集合中的每个元素逐个进行比较. java 对常用的一 ...

  2. Java——HashMap集合详解

    第一章 HashMap集合简介 1.1 介绍 HashMap基于哈希表的Map接口实现,是以key-value存储形式存在,即主要用来存放键值对.HashMap 的实现不是同步的,这意味着它不是线程安 ...

  3. java集合(2)- java中HashMap详解

    java中HashMap详解 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 H ...

  4. Java 集合详解

    一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型.为了满足这些常规的编程需要,我们要 ...

  5. Java集合详解8:Java的集合类细节精讲

    Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...

  6. Java集合详解6:TreeMap和红黑树

    Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...

  7. Java集合详解3:Iterator,fail-fast机制与比较器

    Java集合详解3:Iterator,fail-fast机制与比较器 今天我们来探索一下LIterator,fail-fast机制与比较器的源码. 具体代码在我的GitHub中可以找到 https:/ ...

  8. 【转载】Java 集合详解

    转载:https://www.cnblogs.com/ysocean/p/6555373.html 一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段 ...

  9. Java集合详解8:Java集合类细节精讲,细节决定成败

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

随机推荐

  1. 大数据管理系统架构Hadoop

    Hadoop 起源于Google Lab开发的Google File System (GFS)存储系统和MapReduce数据处理框架.2008年,Hadoop成了Apache上的顶级项目,发展到今天 ...

  2. Apache 首次亚洲在线峰会: Workflow & 数据治理专场

    背景 大数据发展到今天已有 10 年时间,早已渗透到各个行业,数据需 求越来越多,这使得大数据 业务间的依赖关系也越来越复杂,另外也相信做数据的伙伴肯定对如何治理数据也是痛苦之至,再加上现今云原生时代 ...

  3. 新一代大数据任务调度 - Apache DolphinScheduler喜提十大开源新锐项目 & 最具人气项目

    经 10000+ 开发者公开票选,20+专家评审. 10+ 主编团打分,历经数月打磨,11 月 19 日,由InfoQ 发起并组织的[2020中国技术力量年度榜单评选]结果正式揭晓. 2020 年度十 ...

  4. 认识Vue扩展插件

    众所周知,在 Vue 开发中,实现一个功能可以有很多种方式可以选择,这依赖于 Vue 强大的功能(指令.混合.过滤.插件等),本文介绍一下插件的开发使用. Vue 插件 插件通常用来为 Vue 添加全 ...

  5. 【lwip】04-网络数据包流向

    目录 前言 4.1 TCPIP分层与lwip数据共享 4.2 协议栈线程模型 4.3 pbuf 结构体 4.3.1 pbuf的标志位flags 4.4 pbuf的类型 4.4.1 PBUF_RAM类型 ...

  6. pod资源的健康检查-liveness探针的exec使用

    使用探针的方式对pod资源健康检查 探针的种类 livenessProbe:健康状态检查,周期性检查服务是否存活,检查结果失败,将重启容器 readinessProbe:可用性检查,周期性检查服务是否 ...

  7. 从源码中理解Spring Boot自动装配原理

    个人博客:槿苏的知识铺 一.什么是自动装配 SpringBoot 定义了一套接口规范,这套规范规定:SpringBoot在启动时会扫描外部引用jar包中的META-INF/spring.factori ...

  8. Windows DNS服务器的子网掩码排序

    对于跨多个站点部署的应用服务,会在各个站点都有服务器,并且对应不同的IP地址.我们希望每个客户端访问就近的资源.这个时候可以启用Windows DNS服务器中的子网掩码排序(子网优先)netmask ...

  9. Nessus-8.11.1-x64.msi安装包

    希望能给那些和我一样迷茫受挫的小伙伴们一些帮助,这玩意儿下载挺慢的,我把安装包分享出来,如果有博客园账号的,点个赞呗,CSDN那些用着别人的软件还要积分,呸! 08-18更新,截止到现在,已更新到最新 ...

  10. (二)JPA 连接工厂、主键生成策略、DDL自动更新

    (一)JPA的快速入门 2.JPA连接工厂 通过之前的 代码 实现已经清楚的发现了整个的JPA实现步骤,但是这个步骤似乎有一些繁琐了,毕竟最终所关心的一定是EntityManager对象实例,而要想获 ...