目录
一、集合
1.集合是什么?
2.为什么使用集合?
3.集合与数组的对比
4.Java中集合继承层次(UML画图)
二、Collection 接口
1.介绍
2.常用方法
3.示例
三、List接口
1.介绍
2.常用方法
3.示例
四、Collection 集合遍历
1.遍历方式
2.Iterator 接口
3.ListIterator 接口
4.示例
五、集合比较
1.ArrayList和Vector
2.ArrayList和LinkedList
六、Set接口
1.介绍
2.HashSet的存储原理
3.常用方法
4.示例
七、SortedSet 接口
1.常用方法
2.数据结构:二叉树
1.介绍
2.常用方法
3.示例
九、HashSet、LinkedHashSet以及TreeSet之间的区别
十、Collections 工具类
1.常用方法
2.示例
十一、Queue 队列接口
1.介绍
2.常用方法
3.示例
十二、PriorityQueue类
1.介绍
2.示例
十三、Deque 接口
1.介绍
2.常用方法
3.示例
十四、Map 接口
1.介绍
2.常用方法
3.HashMap类
4.遍历Map
5.比较HashMap、HashTable、LinkedHashMap、TreeMap
十五、Stream 流操作
1.介绍
2.常用方法
十六、Predicate 过滤器接口
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
public class TestCollection {
public static void main(String[] args) {
//创建一个集合
Collection c = new ArrayList<>();
//判断集合是否为空,集合元素的个数
System.out.println(c.isEmpty());
//添加
c.add("aa");
c.add("bb");
c.add("cc");
c.add("dd");
//展示集合中的元素
System.out.println(c);
//集合中的元素个数
System.out.println(c.size());
Collection c1 = new ArrayList<>();
c1.add("ee");
c1.add("ff");
c1.add("gg");
//把参数集合中的所有元素添加到当前集合,当前集合只要发生了改变就返回true
c.addAll(c1);
System.out.println(c);
//删除参数指定的元素,只要当前集合发生改变,返回true
c.remove("bb");
System.out.println(c);
//删除指定参数集合中的所有元素,若当前集合发生改变,则返回true
c.removeAll(c1);
System.out.println(c);
//按照条件删除
c.removeIf(new Predicate(){
@Override
public boolean test(String t) {
return t.length() == 3;
}
});//可以使用Lambda表达式
System.out.println(c);
//参数指定的元素在集合中是否包含,包含返回true
System.out.println(c.contains("cc"));
//参数集合中的所有元素在当前集合中是否包含,包含true
System.out.println(c.containsAll(c1));
//把一个字符串数组转换成集合
//转换的集合是Arrays的静态内部类ArrayList,是一个固定长度的集合,不能向集合中添加和删除元素。
List c2 = Arrays.asList(new String[]{"ee","ff"});
c.addAll(c2);
System.out.println(c);
System.out.println(c.contains(c1));
//集合转数组
Object[] obj = c.toArray();
System.out.println(Arrays.toString(obj));
//清空集合
c.clear();
}
}
import java.util.ArrayList;
import java.util.List;
public class TestList {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("aa");//索引0
list.add("bb");//索引1
list.add("cc");//索引2
System.out.println(list);
//可以向索引位置添加元素
list.add(1,"xx");
System.out.println(list);
//获得索引处的元素
System.out.println(list.get(1));
//用第二个参数元素替换索引处的元素
list.set(1,"yy");
System.out.println(list);
list.add("aa");
System.out.println(list);
//返回参数元素在当前集合中第一次出现的位置索引
System.out.println(list.indexOf("aa"));
//返回参数元素在当前集合中最后 一次出现的位置索引
System.out.println(list.lastIndexOf("aa"));
//取子集从起始位置到终止位置(左闭右开)
System.out.println(list.subList(1, 4));
//排序
System.out.println(list);
//参数是:Comparator类型的比较器
//若参数是null,则会按照Comparable方式自然升序排序
list.sort(null);
System.out.println(list);
//指定比较器
list.sort((s1,s2)->s2.compareTo(s1));
System.out.println(list);
}
}
//Iterator迭代器获取及使用方式
Iterator i = list.iterator();
while(i.hasNext()) {
System.out.println(i.next());
}
//ListIterator的获取及使用方式
//ListIterator只能遍历List集合,其他集合不行
ListIterator li = list.listIterator();
while(li.hasNext()){
System.out.println(li.next());
//一边遍历一边插入元素,在最近一次next()访问的元素后插入
li.add("hello");
}
//向前遍历
while (li.hasPrevious()) {
System.out.println(li.previous());
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;
public class TestIterator {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("ee");
System.out.println(list);
//遍历
//1.普通for循环:有索引且索引有顺序
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
//2.增强for
for (String s : list) {
System.out.print(s + " ");
}
//3.
list.forEach(new Consumer() {
@Override
public void accept(String t) {
System.out.println(t);
}
});
list.forEach(t -> System.out.print(t));
list.forEach(System.out::print);
//4.Iterator迭代器
//获得一个迭代器
Iterator i = list.iterator();
// System.out.println(i.next());
// //删除的是最近一次next()访问的元素
// i.remove();
while(i.hasNext()) {
System.out.println(i.next());
//报错:ConcurrentModificationException,并行异常
// list.add("ff");
}
//作用:遍历List集合,其他集合不行
ListIterator li = list.listIterator();
while(li.hasNext()){
System.out.println(li.next());
li.add("hello");
}
//向前遍历
while (li.hasPrevious()) {
System.out.println(li.previous());
}
//6.Iterator迭代器的方法
Iterator i1 = list.iterator();
i1.forEachRemaining(System.out::println);
//7.Stream流的方法
list.stream().forEach(System.out::println);
}
}
存储原理:
自定义Hash:
示例:
import java.util.HashSet;
import java.util.Set;
class Employee{
private int no;
private String name;
public Employee() {
super();
}
public Employee(int no, String name) {
super();
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "Employee [no=" + no + ", name=" + name + "]";
}
//重写hashCode和equals方法,自定义去重规则
@Override
public int hashCode() {
return name.hashCode() + no;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Employee)) {
return false;
}
Employee e = (Employee)obj;
//工号和名字相同,那二者就是相同的
return this.name.equals(e.name) && this.no == e.no;
}
}
public class TestHash {
public static void main(String[] args) {
Set set = new HashSet<>();
set.add(new Employee(1,"郭靖"));
set.add(new Employee(2,"黄蓉"));
set.add(new Employee(3,"杨康"));
boolean res = set.add(new Employee(3,"杨康"));
System.out.println(res);//false,插入失败
System.out.println(set);
}
}
就是Collection 集合中的常用方法,一模一样,真的。
import java.util.HashSet;
import java.util.Set;
public class TestSet {
public static void main(String[] args) {
Set set = new HashSet<>();
//返回boolean,添加成功返回true,添加失败返回false
set.add("aa");
set.add("bb");
set.add("cc");
System.out.println(set);
//重复数据,未添加成功
System.out.println(set.add("aa"));
}
}
import java.util.NavigableSet;
import java.util.TreeSet;
public class TestNavigableSet {
public static void main(String[] args) {
NavigableSet set = new TreeSet<>();
set.add(22);
set.add(11);
set.add(55);
set.add(33);
System.out.println(set);
//小于等于指定参数的最大元素
System.out.println(set.floor(44));
//大于等于指定参数的最小元素
System.out.println(set.ceiling(15));
//降序集合
set.descendingSet().forEach(System.out::println);
//降序迭代器
set.descendingIterator().forEachRemaining(System.out::println);
System.out.println(set);
//移除第一个元素
set.pollFirst();
System.out.println(set);
//移除最后一个元素
set.pollLast();
System.out.println(set);
}
}
类型 | 数据结构 | 元素是否可重复 | 是否有序 |
HashSet | 哈希表 | 不可,唯一的 | 无序 |
LinkedHashSet | 链表+哈希表 | 不可,唯一的。重写hashCode方法和equals方法自定义去重规则。 | 有序,由链表来维护元素添加的顺序 |
TreeSet | 二叉树 | 不可,唯一的。实现Comparable接口,重写compareTo()方法,只要返回0,则认为是重复的。 | 有序,默认自然升序,可以通过Comparator自己指定排序规则。 |
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestCollections {
public static void main(String[] args) {
List list = new ArrayList<>();
//添加
Collections.addAll(list, "aa","cc","bb","xx");
System.out.println(list);
//自然升序排序
Collections.sort(list);
System.out.println(list);
//自定义规则:降序排序
Collections.sort(list, (s1,s2)->s2.compareTo(s1));
System.out.println(list);
//二分查找:前提升序排序 若找到,返回位置索引,未找到,则返回负的插入点-1
System.out.println(Collections.binarySearch(list, "ee"));
//返回集合中最大和最小的元素
System.out.println(Collections.max(list));
System.out.println(Collections.min(list));
//反转集合中的元素
Collections.reverse(list);
System.out.println(list);
list.add("xx");
//返回第二个参数元素在第一个参数集合中出现的次数
System.out.println(Collections.frequency(list, "xx"));
//填充,用第二个参数元素替换掉集合中的所有元素
Collections.fill(list, "hello");
System.out.println(list);
}
}
注意:队列不允许加入null值。只有LinkedList特殊,可以加入null,因为它出现的比较早。
添加 | 删除 | 获取列表头元素 | 操作失败时 |
add | remove | element | 会产生异常 |
offer | poll | peek | (常用下面这些方法)不会产生异常,而是返回特定的值 |
import java.util.LinkedList;
import java.util.Queue;
public class TestQueue {
public static void main(String[] args) {
//队列
Queue q = new LinkedList<>();
//入队:向对尾添加元素
//添加成功返回true,添加失败引发异常
q.add("aa");
q.offer("bb");
//添加成功返回true,添加失败引发异常
q.offer("cc");
System.out.println(q);
q.forEach(System.out::println);
//出队
//删除失败引发异常
// System.out.println(q.remove());
//删除失败,返回null
// System.out.println(q.poll());
// System.out.println(q.poll());
// System.out.println(q);
while(q.size() > 0){
// System.out.println(q.poll());
System.out.println(q.peek());
}
}
}
import java.util.PriorityQueue;
import java.util.Queue;
public class TestPriorityQueue {
public static void main(String[] args) {
//优先队列
//默认自然升序
Queue q = new PriorityQueue<>((s1,s2)->s2.compareTo(s1));
q.add("bb");
q.add("aa");
q.add("cc");
// q.add(null);//报错:空指针异常。
//出队
while(q.size() > 0){
System.out.println(q.poll());
}
}
}
添加 | 删除 | 获取列表头元素 | 操作失败时 |
addFirst addLast |
removeFirst removeLast |
getFirst getLast |
会产生异常 |
offerFirst offerLast |
pollFirst pollLast |
peekFirst peekLast |
不会产生异常,而是返回特定的值 |
import java.util.ArrayDeque;
import java.util.Deque;
public class TestDeque {
public static void main(String[] args) {
//队列:先进先出
Deque q = new ArrayDeque<>();
//入队
q.addLast("aa");
q.add("bb");
q.offer("cc");
q.offerLast("dd");
//出队
while(q.size() > 0){
System.out.println(q.pollFirst());
// System.out.println(q.poll());
}
//栈:后进先出
Deque q1 = new ArrayDeque<>();
//入栈
/*q1.addFirst("aa");
q1.offerFirst("bb");
q1.offerFirst("cc");*/
q1.push("aa");
q1.push("bb");
q1.push("cc");
//出栈
while(q1.size() > 0){
// System.out.println(q1.pollFirst());
// System.out.println(q1.poll());
System.out.println(q1.pop());
}
}
}
示例
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class TestMap {
public static void main(String[] args) {
//Map
//Hash表的数组初始容量是16
HashMap map = new HashMap<>();
Set set = new HashSet<>();//可以看到底层调用的就是HashMap
//size() 键值对的数目
System.out.println(map.size());
//空的 true
System.out.println(map.isEmpty());
//添加
map.put(11, "aa");
map.put(22, "bb");
map.put(33, "cc");
System.out.println(map);
//键是唯一,都是Set,获得键的集合
System.out.println(map.keySet());
//获得值的集合
System.out.println(map.values());
//指定的参数的键对应的键值对信息是否包含在集合中,存在返回true
System.out.println(map.containsKey(11));
//指定的参数的值对应的键值对信息是否包含在集合中,存在返回true
System.out.println(map.containsValue("aa"));
//根据指定的键删除对应的键值对
map.remove(33);
//替换(修改)
map.replace(11, "hello");
System.out.println(map);
map.clear();
System.out.println(map.size());
}
}
注:HashMap的源码要认真阅读
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class TestMap {
public static void main(String[] args) {
HashMap map = new HashMap<>();
//添加
map.put(11, "aa");
map.put(22, "bb");
map.put(33, "cc");
// System.out.println(map);
map.put(33, "hello");
// System.out.println(map);
//遍历
//1.集合forEach方法
/*map.forEach(new BiConsumer() {
@Override
public void accept(Integer t, String u) {
System.out.println(t + ":" + u);
}
});*/
map.forEach((k,v)->System.out.println(k + ":" + v));//lambda表达式
//2.Iterator
/*map.keySet().iterator().forEachRemaining(new Consumer() {
@Override
public void accept(Integer t) {
System.out.println(t);
}
});*/
map.keySet().iterator().forEachRemaining(System.out::println);
/*map.values().iterator().forEachRemaining(new Consumer(){
@Override
public void accept(String t) {
System.out.println(t);
}
});*/
map.values().iterator().forEachRemaining(System.out::println);
//3.键值对的遍历Entry
Iterator> it = map.entrySet().iterator();
while(it.hasNext()){
Entry e = it.next();
System.out.println(e.getKey() + ":" + e.getValue());
}
}
}
末端方法:统计出一个最终的结果,流就被消耗掉了,也就是释放了,不能再用了。包括
末端方法示例:
import java.util.stream.IntStream;
public class TestStream {
public static void main(String[] args) {
//Stream
//创建一个IntStream
IntStream i = IntStream.builder().add(11).add(22).add(33).add(44).build();
//末端方法
// System.out.println(i.max());
//最大值
// System.out.println(i.max().getAsInt());
//最小值
// System.out.println(i.min().getAsInt());
//总和
// System.out.println(i.sum());
//平均值
// System.out.println(i.average().getAsDouble());
//流中元素的个数
// System.out.println(i.count());
//流中所有元素都满足条件,结果是true,否则为false
/*System.out.println(i.allMatch(new IntPredicate() {
@Override
public boolean test(int value) {
// TODO Auto-generated method stub
return value > 33;
}
}));*/
// System.out.println(i.allMatch(v->v>3));
//流中只要有一个元素满足条件,结果就是true,否则false
System.out.println(i.anyMatch(v->v>33));
}
}
中间方法:使用中间方法可以得到一个新的流,新的流可以继续调用方法进行操作。包括
中间方法示例:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.ToIntFunction;
class Student implements Comparable{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Student arg0) {
// TODO Auto-generated method stub
return this.age - arg0.age;
}
}
public class TestStream3 {
public static void main(String[] args) {
//中间方法
List list = new ArrayList<>();
Student guojing = new Student("郭靖",22);
Student yangkang = new Student("杨康",21);
Student huangrong = new Student("黄蓉",19);
Collections.addAll(list, guojing,yangkang,huangrong,huangrong,guojing,yangkang);
list.stream().forEach(System.out::println);
//中间方法,返回一个值
//1.过滤
list.stream().filter(stu->stu.getAge()>20).forEach(System.out::println);
//2.映射
list.stream().map(new Function(){
@Override
public String apply(Student t) {
return t.getName();
}
}).forEach(System.out::println);
list.stream().mapToInt(new ToIntFunction() {
@Override
public int applyAsInt(Student value) {
return value.getAge();
}
}).forEach(System.out::println);
//3.
// list.stream().forEach(System.out::println);
//3.去除重复的元素
list.stream().distinct().forEach(System.out::println);
//4.排序
list.stream().sorted().forEach(System.out::println);
//5.peek作用与forEach一样,peek是中间方法,forEach是末端方法
list.stream().peek(System.out::println).forEach(System.out::println);
System.out.println(list.stream().peek(System.out::println).count());
//取前几个数据
list.stream().limit(2).forEach(System.out::println);
//7.略过前几个数据
list.stream().skip(1).forEach(System.out::println);
}
}
直接看例程:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
class Child{
private String name;
private int age;
public Child(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Child [name=" + name + ", age=" + age + "]";
}
}
public class TestPredicate {
public void childInfo(List list, Predicate p){
for (Child child : list) {
if(p.test(child)){
System.out.println(child);
}
}
}
public static void main(String[] args) {
List list = new ArrayList<>();
list.add(new Child("guojing" ,22));
list.add(new Child("yankan" ,33));
list.add(new Child("huangrong" ,20));
TestPredicate t = new TestPredicate();
t.childInfo(list, e->e.getAge()>30 && e.getName().contains("g"));
}
}