Java集合
来源:互联网 发布:树上10只鸟 程序员 编辑:程序博客网 时间:2024/06/09 13:55
Java集合就像是一种容器,可以将多个对象(其实是对象的引用)丢入其中。Java集合分为Set、List、Queue和Map四大类,集合类又称容器类。
- Set代表无序不重复的集合
- List代表有序可重复的集合
- Queue代表队列集合
- Map代表映射关系集合
有图可知,如果访问List集合,我们可以通过元素的索引来访问,如果访问Map集合中的元素,可以根据每项的key来访问其value,但是如果访问set集合中的元素,则只能根据元素本身来访问(因而不能重复)。
Java5之前,Java集合会丢失放入其中的对象的数据类型,把所有对象都当成Object类型来处理。Java5 增加泛型之后,Java集合可以记住容易中对象的数据类型,从而可以编写出更简洁、更健壮的代码。
1、集合概述
加入我们需要存放多个数据,可以考虑放在数组中,但是放在数组中的问题是,数组长度不可变,而且数组不能保存映射关系的数据。
为了保存不确定长度的数据和保存具有映射关系的数据(也被称为关联数组),Java提供了集合类。所有集合类都位于java.util包下,后来为了处理多线程环境下的并发安全问题,java 5在java.util.concurrent包下提供了一些多线程支持的集合类。
集合类和数组不一样,数组既可以保存基本类型数据,又可以保存引用类型的数据(其实保存的就是引用)。但是集合类中只能保存引用类型的数据。
Java集合类主要由Collection和Map两个接口派生出来的,这两个是根接口,其下包含了很多子接口和实现类。
其中颜色重的表示最常用的实现类。
2、Collection和Iterator接口
Collection接口是Set、List和Queue的父接口,因而Collection接口中定义的方法,是三个子接口的公共方法。
- 添加对象,add(o)、addAll(c)、
- 查找对象,contains(o)、containsAll(c)
- 删除对象,remove(o)、removeAll(c)、retainAll(c)、clear
- 容器大小,isEmpty()、size()
- 其他,iterator()、toArray()
2.1 使用Lambda表达式来遍历集合
Java8中提供了新的函数式接口包以及4个函数式接口。
java.util.function这个包,提供了4个核心接口,
功能型接口,Function
public Interface Function<T,R>{ public R apply(T t);}
此接口需要接收一个参数,并且返回一个处理结果。
消费型接口,Consumer
public Interface Consumer<T>{ public void accept(T t);}
此接口只负责接收数据,并不返回处理结果。
- 供给接口,Supplier
public interface Supplier<T>{ public T get();}
此接口不接受参数,但可以返回结果
4. 断言型接口,Predicate
public interface Predicate<T>{
public boolean test(T t);
}
进行判断操作使用
Jdk1.8 中有以上的四个功能型接口,所以一般很少会由用户定义新的函数式接口。
观察函数式接口,特征是接收参数,并且返回处理结果
String有个public boolean startsWith(String str)
Function<String, Boolean> fun = "##hello" :: startsWith;Syso(fun.apply("##")); //返回true
消费型接口
class MyDemo{ public void print(String s){ //此方法有参数无返回值 syso(s); }}//mainConsumer<String> cons = new MyDemo() :: print;cons.accept("Hello Java");
供给型接口,
例如String类的toUpperCase()方法,public String toUpperCase();
Supplier sup = "hello" :: toUpperCase();syso(sup.get());
断言型接口
String
Predicate<String> pre = "hello" :: equalsIgnoreCase;syso(pre.test("Hello")); //true
这几个接口包含了所有可能出现的方法引用,也是函数式接口的代表,有许多的接口与他们类似,例如Function中有个DoubleToIntFunction,其中的apply方法int applyAsInt(double value); 只能接收double转换为int。
3、Set集合
Set集合和Collection基本相同,没有添加额外的方法,实际上Set集合就是Collection,只是行为略有不同,不能添加重复的元素。
如果把两个相同的元素add()到同一个集合,会返回false。
Set集合有三种常见的实现类,HashSet、TreeSet、EnumSet。
3.1 HashSet
HashSet是Set接口的典型实现类,我们使用的Set大多数都是这个Set。HashSet是按照Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet具有以下特点:
- 不能保证元素的排列顺序,顺序可能与添加元素的顺序不一致;
- HashSet不是同步的,加入有多个线程来操作同一个HashSet,必须通过代码来同步;
- 元素值可以为null。
当向HashSet中存入一个值时,HashSet会调用这个对象的hashCode()方法,获得该对象的hash值,然后根据这个值决定其在HashSet中存储的位置。如果两个对象通过equals方法得到的值相同,但是他们的Hash值不同,他们仍将被存储在不同的位置。
HashSet判断两个元素对象相等的标准是equals()方法比较相等,并且两个对象的hashCode()值也相等。
要注意的一点是,当把一个对象放入到HashSet中时,如果重写了这个对象对应类的equals方法,则应该也重写该类的hashCode()方法。规则是,如果两个对象,通过equals方法返回true,则两个对象的hashCode值也应该相同。如果两个hashCode不同,则会被Set都存储,则Set中就会存在两个值一样的对象,这是不符合Set规范的。如果两个对象的hashCode值相同,但是equals比较的值不同,这个也是不对的。如果两个对象的hashCode相同,HashSet会试图将他们保存在同一个位置,结果发现已经有数据,则会在这个位置使用链式结构来保存多个对象。HashSet访问集合元素时会根据元素的HashCode值来快速定位,同一个位置多个值会导致性能下降。
hash算法的价值在于速度,HashSet类似于数组,数组也包含多个元素,每个元素都有索引,如果需要访问元素,只需要提供索引,然后根据索引计算元素在内存中的存储位置。为什么不直接用数组,而用HashSet呢,因为数组是连续不可变长度的存储。HashSet使用hashCode做索引,不要求索引是连续的,长度也是可变,可以根据索引快速定位到内存地址。
当向HashSet中添加可变的对象时,必须十分小心,如果修改集合中的对象,有可能导致该对象与集合中的其他对象相等,从而导致HashSet无法正确的访问到该对象。
3.2 LinkedHashSet类
HashSet还有个子类,LinkedHashSet类,它也是使用对象的hashCode来决定对象的存储位置,但它同时使用链表来维护元素的次序,这样使得元素看起来是以插入的顺序来保存的。也就是说,遍历LinkedHashSet时,会以其插入顺序来放访问元素。但是其仍然是HashSet,仍然不会允许元素重复的。
LinkedHashSet需要维护元素的插入顺序,因而性能比HashSet要略低,但是在迭代Set中全部元素时具有很好的性能,因为其是你链表来维护内部顺序的。
3.3 TreeSet类
TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
相比与HashSet,TreeSet额外提供了几个跟有序相关的方法,比如访问第一个、前一个、访问最后一,后一个,截取子TreeSet等方法。
与HashSet使用hash算法来决定元素的位置不同,TreeSet使用红黑树的数据结构来存储集合元素。Tree
- Java集合:集合框架
- java集合---set集合
- JAVA 集合 的 集合
- 【集合】Java集合对比
- JAVA集合-Map集合
- JAVA集合-Set集合
- JAVA集合-List集合
- java集合------Map集合
- Java集合----List集合
- Java集合----Set集合
- Java集合----Map集合
- JAVA集合
- JAVA集合
- Java集合
- JAVA集合
- Java集合
- Java集合
- java 集合
- 嵌入式面试题——ARM面试题(三)
- Angular企业级开发(8)-控制器的作用域
- 大数据平台cloudera manager安装
- C语言perror( )函数
- 设计模式之桥接模式
- Java集合
- 【LEETCODE】 Find Largest Value in Each Tree Row javascript实现
- 左偏树/斜堆/可并堆-洛谷P3377 【模板】左偏树(可并堆)
- Practice3_7_vector_sort_struct_gold_silver_bronze_playerName3
- HOJ 2201 题解
- 安装caffe(CPU版)遇到的问题
- hibernate之constrained详解
- 文章标题 POJ 1151 : Atlantis (线段树+扫描线)
- 有感而发