一:总体介绍:
Java集合框架介绍
集合可以看作是一种容器,用来存储对象信息。所有集合类都位于java.util包下,但支持多线程的集合类位于java.util.concurrent包下。
Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List、Set、Queue、Map四种接口体系,(注意:Map不是Collection的子接口)。
其中List代表了有序可重复集合,可直接根据元素的索引来访问;Set代表无序不可重复集合,只能根据元素本身来访问;Queue是队列集合;Map代表的是存储key-value对的集合,可根据元素的key来访问value。
Java集合和数组的区别:
- 已定义集合的大小可变,而已定义的数组大小不可变(注意:集合内部实现机制也用到了对象数组,只是通过数组的复制或链式存储的方式使其从外部看起来是可变的,而其本身并未颠覆数组大小不可变这一观点)
- 数组可以存储基本数据类型和引用类型,而集合只能存储引用类型,例如传入add方法中的int会被自动封装成Integer类型
- 数组只能存储相同类型的数据,而集合如未确定泛型的具体类型,则可存储任意引用类型数据
Guava集合框架介绍
Guava 是一款 Google 开源工具类,包含许多 Google 内部 Java
项目依赖的核心类。Guava 扩展 Java 基础类工程,比如集合,并发等,也增加一些其他强大功能,比如缓存,限流等功能。另外 Guava 推出一些类,如 Optional
,甚至被 Java 开发者学习,后续增加到 JDK 中。Guava 创造很多 JDK 没有,但是我们日常却明显有用的新集合类型。这些新类型使用 JDK 集合接口规范,所以使用方法与 JDK 集合框架差不多,并没有增加很多使用难度。
集合接口 | 属于JDK还是Guava | 对应的Guava工具类 |
Collection | JDK | Collections2:不要和java.util.Collections混淆 |
List | JDK | Lists |
Set | JDK | Sets |
SortedSet | JDK | Sets |
Map | JDK | Maps |
SortedMap | JDK | Maps |
Queue | JDK | Queues |
Multiset | Guava | Multisets |
Multimap | Guava | Multimaps |
BiMap | Guava | Maps |
Table | Guava | Tables |
二:接口及类详解【JAVA】
Iterable<T> 接口
常用方法:
方法名或属性名称 | 描述 | 注意事项 | 备注 |
---|---|---|---|
Iterator<T> iterator(); |
返回每个元素的迭代器 |
||
default void forEach(Consumer<? super T> action) |
循环操作每个元素 |
|
|
default Spliterator<T> spliterator() |
创建一个spliterator |
重点方法介绍及代码示例
/** * iteable测试类 */ public class TestItearble { // 返回迭代器,hasNext方法判断是否有下一个元素 next方法取下一个元素 public static void testIterator(List<Integer> list) { Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } // foreach 内部用的还是iterator public static void testForeach(Set<String> set) { set.forEach(System.out::println); } public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(3); list.add(4); testIterator(list); Set<String> set = new HashSet<>(); set.add("one"); set.add("three"); set.add("four"); set.add("one"); testForeach(set); } |
spliterator是java1.8新提出的能够进行并行遍历的迭代器.首先, iterator是专门用于迭代集合元素的方法,在List类中就有iterator()方法.集合通过调用Iterator方法,可以对该集合进行循环,效果就相当于是使用了for循环,但是iterator的好处就是不论是List,还是Map,都可以通过iterator进行遍历.但是,通过iterator和for循环一样,都是单线程的操作,Spliterator也用于遍历数据源中的元素,但它是为了并行执行而设计的。Java 8已经为集合框架中包含的所有数据结构提供了一个默认的Spliterator实现。集合实现了Spliterator接口,接口提供了一个spliterator方法。详解可见:https://blog.csdn.net/sl1992/article/details/100149187?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param
public class TestSplitror { private static class Thread<T> extends java.lang.Thread { private final Spliterator<T> list; private Thread(Spliterator<T> list) { this.list = list; } @Override public void run() { list.forEachRemaining(System.out::println); } } public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 2000; i++) { list.add("split" + i); } // 拆分迭代器 Spliterator<String> spliterator = list.spliterator(); Spliterator<String> stringSpliterator = spliterator.trySplit(); Thread<String> stringthread = new Thread<>(spliterator); Thread<String> stringthread1 = new Thread<>(stringSpliterator); stringthread.start(); stringthread1.start(); while (true) { if (stringthread.isAlive() || stringthread1.isAlive()) { try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } else { break; } } System.out.println("main end"); } } |
Collection<E> 接口
常用方法
方法名或属性名称 | 描述 | 注意事项 | 备注 |
---|---|---|---|
int size(); |
返回集合的元素数量 |
如果元素数量超过Integer.MAX_VALUE返回Integer.MAX_VALUE. |
|
boolean isEmpty(); |
返回集合是否没有元素 |
||
boolean contains(Object o); |
如果集合有该元素返回true |
ClassCastException 元素类型不相容 |
|
Object[] toArray(); |
返回一个装有改集合元素的数组 |
排序 |
<T> T[] toArray(T[] a)该方法可以对返回的数组类型进行精确控制。而非像toArray方法一样返回 |
boolean add(E e); |
添加一个元素,添加成功返回true |
|
|
boolean remove(Object o); |
移除一个元素,移除成功返回true |
|
|
boolean containsAll(Collection<?> c); |
是否存在当前集合中的所有元素 |
|
|
boolean addAll(Collection<? extends E> c); |
添加当前集合中的所有元素 |
|
|
boolean removeAll(Collection<?> c); |
移除当前集合中的所有元素 |
|
|
default boolean removeIf(Predicate<? super E> filter) |
根据给定的公式移除元素 |
|
|
default Stream<E> stream() |
返回streeam流 |
||
default Stream<E> parallelStream() |
返回并行stream流 |
重点方法介绍及代码示例
add() 向集合中添加一个元素。集合更改则添加成功返回true,如果该集合不允许重复并且已经包含指定的元素。返回false。部分子类的add方法可能会限制添加到集合中的元素类型,或者不会将NULL添加到集合中。
public class TestCollectionApi { public static void main(String[] args) { Collection set = new HashSet<>(); boolean one = set.add("one"); boolean one1 = set.add("one"); System.out.println("set第一次添加add" + one); System.out.println("set第二次添加add" + one1); Collection list = new ArrayList<>(); boolean one2 = list.add("list"); boolean one3 = list.add("list"); System.out.println("list第一次添加add" + one2); System.out.println("list第二次添加add" + one3); } } 返回结果为:true false true true |
List<E>接口
一个排序的集合(也被称作序列),接口使用者可以精确控制每个元素在集合中的插入位置,用户可以根据integer类型的索引访问和搜索集合中的元素。不像set,集合通常允许重复的元素,如果他们允许null元素存在的话,也可以存在重复的null。
方法名或属性名称 | 描述 | 注意事项 | 备注 |
---|---|---|---|
default void replaceAll(UnaryOperator<E> operator) |
将此列表中的每个元素替换为对该元素应用运算符的结果。 | ||
default void sort(Comparator<? super E> c) |
根据明确的比较器进行排序 | ||
E get(int index); |
返回该位置的元素 | ||
E set(int index, E element); |
用明确的元素替换明确位置的元素。 | ||
void add(int index, E element); |
插入元素到固定的位置,原该位置元素及后面的元素索引加一。 | ||
E remove(int index); |
移除具体位置的元素,后面的元素索引减一 | ||
int indexOf(Object o); |
返回该元素的索引位置或者返回-1(如果不存在) | ||
ListIterator<E> listIterator(); |
返回一个list迭代器 | int lastIndexOf(Object o);返回最后一个该元素的索引位置或者-1(不存在) |
|
List<E> subList(int fromIndex, int toIndex); |
返回一个前闭后开的视图。 |
重点方法介绍及代码示例
public class TestListApi { public static void main(String[] args) { List<String> list = new LinkedList<>(); list.add("a"); list.add("b"); list.add("c"); list.set(1, "d"); System.out.println(list); list.add(1, "k"); System.out.println(list); list.replaceAll(x -> { if (x.equals("a")) { return "tt"; } return x; }); System.out.println(list); list.sort(String::compareTo); System.out.println(list); List<String> list1 = list.subList(0, 2); list1.set(0, "kkkk"); System.out.println(list); } } 返回结果为: [a, d, c] [a, k, d, c] [tt, k, d, c] [c, d, k, tt] [kkkk, d, k, tt] |
Set<E>接口
元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
Set接口有两个实现类:HashSet(底层由HashMap实现),LinkedHashSet
SortedSet接口有一个实现类:TreeSet(底层由平衡二叉树实现)
Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。
HashSet : 为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
TreeSet : 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
LinkedHashSet : 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
方法名或属性名称 | 描述 | 注意事项 | 备注 |
---|---|---|---|
boolean contains(Object o); |