集合(上)
1、数据,指能够输入计算机中,由计算机所处理的元素。结构, 指数据之间的关系。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
常用的数据结构有:
链表
堆栈
队列
树
哈希表
说明:堆栈、队列、链表为线性存储结构(线性表),即多个元素的有序序列。堆栈,队列为操作受限的线性表。
2、链表:链表存储的数据元素称为结点,在链表中,各个结点是有序的。
每个结点分为两个部分:
数据域
指针域
根据链表指针域的数量,可以将链表分为:
单向链表
双向链表
单向链表:
双向链表:前一个指向上一个结点,中间是数据域,后一个指向下一个结点。(循环双向链表)
数组与链表的不同:
存储方式: 数组在内存中时连续存储,链表在内存中不是连续存储。
3、堆栈
堆栈(简称栈)是一种操作受限的线性表,只能在表头增加或删除元素。我们通常将栈使用竖直的方式来表示,因此,表尾称为“栈顶”,表头称为“栈底”。栈表现的特征为后进先出。( LIFO)
4、队列
队列是一种操作受限的线性表。只能在队尾增加元素,在队头删除元素。
队列表现的特征为先进先出(FIFO)。
队列分为:单端队列、双端队列
当队列的两端都可以增加与删除元素时,这种队列称为双端队列。双端队列可以同时实现队列与堆栈的特征。
5、树
树是由结点集及连接每对结点的有向边集组成。
如果存在有向边连接A到B,则A为B的父节点(父亲),B为A的子节点(孩子)。没有父节点的结点称为根,没有子节点的结点称为叶子。具有相同父节点的各结点称为兄弟。
从根到某一节点经过的边数称为路径长度。
6、二叉树
二叉树是一种树形结构,其特征是任意结点的孩子数不超过两个。一棵二叉树要么为空,要么由根、左子树与右子树组成(左右子树可能为空)。
一棵深度(树的层数)为m,且具有2m-1个结点的二叉树称为满二叉树。
当一棵二叉树的所有结点编号(从上到下,从左到右进行)都与满二叉树一致时,该二叉树称为完全二叉树。
7、树的遍历
分为三种:先序遍历、中序遍历、后序遍历
先序:先根》左子树》右子树
中序:左子树》根》右子树
后序:左子树》右子树》根
8、哈希表
将一组关键字映射到一个有限的地址集上,这种表称为哈希(散列)表。哈希表中,关键字映射到相应的地址需要使用相关的算法,称为哈希函数。关键字映射后所得的存储地址称为哈希(散列)地址。
9、集合
集合就是一系列元素的整体。
集合就像是一个容器,可以存放与获取元素,与数组相似。不同的是,集合提供了很多有用的方法,用来操作与管理集合内的元素,而数组提供的方法很有限。
集合和数组对比:
缺点:集合的实现比数组更加复杂,因此,其性能上不如数组。
优点:
集合时不定长的,底层可以根据需要实现自动的扩容。而数组是定长的,我们在创建数组的时候就需要指定数组的长度。
集合提供了很多有用的方法,可以操作集合内的元素,而数组提供的功能相对有限。
10、集合框架

11、集合分类:
Collection接口提供元素存储。
Map接口提供映射存储(键值对)
package day14;
/*
* 集合
* 集合与数组类型,类比一个容器,可以向里面加入元素。
* 集合与数组的对比:
* 缺点:集合的实现比数组更加复杂,因此,其性能上不如数组。
* 优点:
* 1 集合是不定长的,底层可以根据需要实现自动的扩容。
* 而数组是定长的,我们在创建数组的时候就需要指定数组的长度。
* 2 集合提供了很多有用的方法,可以操作集合内的元素,而数组
* 提供的功能相对有限。
*/
public class CollectionTest {
public static void main(String[] args) {
}
}
12、
Collection 最基本的集合接口。用来存储一系列元素。
Set继承Collection接口,不含有重复元素。
List 继承Collection接口,List是有序集合,能精确控制每个元素插入的位置,可使用索引来访问List中的元素。
Queue继承Collection接口。通常实现先进先出(FIFO)的规则,但这不是必须的。删除(获取)元素时,会获取队列头部的元素。先进先出的队列中,增加元素会追加到队列的末尾。
Deque继承Queue接口。可同时在队列的两端增加与删除元素。
Map接口提供key(键)到value(值)的映射,是一组成对的键-值对象。一个Map中不能有相同的key,每个key只能映射一个value。
SortedSet继承Set接口,内部元素按照升序排列。
SortedMap继承Map接口,key按照升序排列。
13、collection常用方法
package day14;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionMethod {
public static void main(String[] args) {
Collection<Integer> c = new ArrayList<>();
for (int i = 0; i < 10; i++) {
c.add(i);
}
// 返回集合中元素的个数。
System.out.println(c.size());
// 判断集合是否为空(集合元素个数是否为0),为空
// 返回true,否则返回false。
System.out.println(c.isEmpty());
// 判断集合中是否含有参数指定的元素(根据元素的equals方法)。
// 有返回true,否则返回false。
System.out.println(c.contains(5));
// 返回集合的迭代器,可以用来遍历集合每一个元素。
Iterator<Integer> iter = c.iterator();
// 将集合转换成数组,数组中的元素就是之前集合中的元素。
// 返回Object[]类型。
Object[] o = c.toArray();
Integer[] inte = new Integer[c.size()];
Integer[] i = c.toArray(inte);
// 向集合中加入参数指定的元素。如果当前集合发生改变,
// 返回true,否则返回false。
c.add(11);
// 删除集合中参数指定的元素。如果当前集合发生改变,
// 返回true,否则返回false。
c.remove(1);
Collection<Integer> c2 = new ArrayList<>();
c2.add(5);
c2.add(100);
// 判断当前集合是否包含参数指定集合中所有的元素。是
// 则返回true,否则返回false。
System.out.println(c.containsAll(c2));
// 将参数集合中所有的元素加入到当前集合中。如果当前集合
// 发生改变,返回true,否则返回false。
System.out.println(c.addAll(c2));
// 删除当前集合中存在,并且参数集合中也存在的所有元素。
// 如果当前集合发生改变,返回true,否则返回false。
System.out.println(c.removeAll(c2));
// 删除满足条件的所有元素。
c.removeIf(t -> t > 5);
System.out.println(c);
Collection<Integer> c3 = new ArrayList<>();
c3.add(100);
c3.add(101);
Collection<Integer> c4 = new ArrayList<>();
c4.add(100);
c4.add(102);
// 保留当前集合中存在,并且参数集合中也存在的所有元素。
// 即删除所有当前集合中存在,参数集合中不存在的所有元素。
// 如果当前集合发生改变,返回true,否则返回false。
c3.retainAll(c4);
System.out.println(c3);
// 删除集合中所有的元素。
c3.clear();
}
}
14、遍历集合方式
可以使用以下方式来遍历集合: 使用iterator接口。(原始方法) 使用iterator接口。(新增方法) 使用增强型for循环。 使用forEach方法。 使用聚合操作。
package day14;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.omg.Messaging.SyncScopeHelper;
public class Tranverse {
public static void main(String[] args) {
Collection<Integer> c = new ArrayList<>();
for (int i = 0; i < 5; i++) {
c.add(i);
}
/*
* 1 使用Iterator迭代器(原始的方法)
*/
// 返回集合的迭代器,迭代器的指针初始指向第一个元素之前。
Iterator<Integer> iter = c.iterator();
// 判断是否还有下一个元素,如果存在下一个元素,返回true,
// 否则返回false。
while (iter.hasNext()) {
// 获取下一个元素。同时移动当前的指针,指向当前
// 返回的元素。
Integer integer = iter.next();
System.out.println(integer);
// System.out.println(iter.next());
// 使用迭代器迭代的过程中,不能通过集合引用
// 删除元素,否则会产生ConcurrentModificationException异常。
// c.remove(0);
// 如果要在迭代的过程中删除元素,可以调用迭代器的
// remove方法。该方法会删除最后一次调用next
// 返回的元素。
// iter.remove();
}
/*
* 2 使用Iterator接口迭代器(JDK1.8新增的方法)
*/
Iterator<Integer> iter2 = c.iterator();
// 对每一个剩下的元素(当前迭代器
// 指针之后的元素)执行指定的操作。
iter2.forEachRemaining(t -> System.out.println(t));
// 使用方法引用
iter2.forEachRemaining(System.out::println);
/*
* 3 使用增强型for循环遍历
*/
for (Integer i : c) {
System.out.println(i);
}
/*
* 4 使用集合类的forEach方法。
*/
c.forEach(t -> System.out.println(t));
c.forEach(System.out::println);
/*
* 5 使用聚合操作
*/
c.stream().forEach(System.out::println);
}
}
15、List接口的方法
/*
* List接口的方法
*/
package day14;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListMethod {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 5; i > 0; i--) {
list.add(i);
}
List<Integer> list2 = new ArrayList<>();
for (int i = 5; i < 10; i++) {
list2.add(i);
}
// 将参数集合中的元素加入到当前list的最后面。(追加)。
// list.addAll(list2);
// 将参数集合(第2个参数)中的所有元素加入到当前集合
// 指定的位置(第1个参数)处。
// list.addAll(3, list2);
// list.forEach(System.out::println);
// 对List中的每一个元素进行替换。
// list.replaceAll(t -> t * 2);
// 对list元素进行排序。参数为比较器,如果想实现元素
// 自然排序,参数传递null值。
// list.sort(null);
// list.sort((a, b) -> a - b);
// 返回指定索引位置的元素。
// list.get(0);
// 将索引位置的元素(第1个参数)使用第二个参数指定
// 的元素进行替换。
// list.set(0, 1000);
// 在索引位置(第1个参数)插入元素(第二个参数指定)
// list.add(0, 1000);
// 删除参数指定位置(索引)的元素。
// list.remove(0);
// 返回参数元素在List中首次出现的位置。
// 如果没有出现,返回-1。
System.out.println(list.indexOf(12));
// 返回参数元素在List中最后一次出现的位置。
// 如果没有出现,返回-1。
System.out.println(list.lastIndexOf(12));
// list.forEach(System.out::println);
// 返回List特有的迭代器。指针指向第一个元素之前。
ListIterator<Integer> li = list.listIterator();
// 返回List特有的迭代器。指针指向参数指定位置的元素之前。
// 下次调用next()方法会返回参数指定位置的那个元素。
li = list.listIterator(2);
// 返回子List,第1个参数指定开始点。第2个参数指定结束点。
// 包括起始点,不包括结束点。
List<Integer> sub = list.subList(1, 3);
}
}
16、
ArrayList与LinkedList List接口有两个常用的实现类: ArrayList LinkedList 二者的不同在于: ArrayList底层使用数组来实现的,而 LinkedList是使用链表(数据域+指针域)的方式实现的。当随 机访问元素操作多的时候,优先使用ArrayList,当增加与删除 操作多的时候,优先使用LinkedList。
package day14;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorMethod {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(11);
list.add(33);
ListIterator<Integer> i = list.listIterator(1);
// 判断是否存在前一个元素,如果存在,返回true,
// 否则返回false。
System.out.println(i.hasPrevious());
// 返回前一个元素。
i.previous();
// 返回下一个元素的索引。即下次调用next方法返回元素的索引。
i.nextIndex();
// 返回前一个元素的索引。即下次调用previous返回元素的索引。
i.previousIndex();
// 删除最后一次调用next或previous方法返回的元素。
i.remove();
// 将最后一次调用next或previous方法返回的元素设置(替换)
// 成参数指定的元素。
i.set(2);
// 在当前指针位置之前进行插入。(对下次调用next没有影响)。
i.add(100);
}
}
17、set接口
/*
* Set接口
* Set接口中的元素是不允许重复。是否重复
* 根据equals方法(或compareTo方法)进行判断的。
* Set接口没有新增的方法(相对Collection接口)。
*/
18、hashSet实现类
/*
* HashSet实现类
*/
package day14;
import java.util.HashSet;
import java.util.Set;
public class HashSetTest {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(100);
set.add(-2);
set.add(16);
set.add(-212);
// 没有加入成功,返回false。因为元素重复了。
// System.out.println(set.add(-2));
// System.out.println(set.size());
// HashSet使用元素的哈希码(hashCode)来计算
// 元素的存储位置。因此,我们不能保证元素获取的顺序
// 与元素加入时的顺序是一致的。
set.forEach(System.out::println);
}
}
19、LinkedHashSet
package day14;
import java.util.LinkedHashSet;
import java.util.Set;
/*
* LinkedHashSet
* LinkedHashSet是HashSet的子类,其底层使用一个
* 双向链表来维护元素的顺序,因此,获取元素时(遍历元素
* 时),可以保证获取的顺序与元素加入时的顺序一致。
*/
public class LinkedHashSetTest {
public static void main(String[] args) {
Set<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(-2);
set.add(16);
set.add(-212);
set.forEach(System.out::println);
}
}
20、SortedSet
/*
* SortedSet接口
* 规范:加入的元素可以自动实现升序排列。
*/
package day14;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortedSetTest {
public static void main(String[] args) {
SortedSet<Integer> set = new TreeSet<>();
set.add(100);
set.add(20);
set.add(50);
set.forEach(System.out::println);
//TreeSet无参的构造器,使用自然排序。
SortedSet<Box> set2 = new TreeSet<>();
set2.add(new Box(100));
set2.add(new Box(20));
set2.add(new Box(50));
set2.forEach(System.out::println);
// 也可以在创建TreeSet对象时,指定比较器。
// 这样就可以指定自己的比较规则。如果我们显式的
// 指定了比较器,此时就不会使用自然排序。
SortedSet<Box> set3 = new TreeSet<>((a, b) -> b.getValue() - a.getValue());
set3.add(new Box(100));
set3.add(new Box(20));
set3.add(new Box(50));
set3.forEach(System.out::println);
}
}
class Box implements Comparable<Box> {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Box(int value) {
super();
this.value = value;
}
@Override
public int compareTo(Box o) {
return value - o.value;
}
@Override
public String toString() {
return "Box [value=" + value + "]";
}
}
21、SortedSet接口
package day14;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortedSetMethod {
public static void main(String[] args) {
SortedSet<Integer> set = new TreeSet<>();
// SortedSet<Integer> set = new TreeSet<>((a, b) -> b - a);
for (int i = 0; i < 10; i++) {
set.add(i);
}
// 返回比较器,如果没有指定比较器,返回null。
// System.out.println(set.comparator());
// 返回子SortedSet,第1个参数指定起始点,第2个参数指定
// 终止点,包括起始点,不包括终止点。
SortedSet<Integer> subSet = set.subSet(3, 100);
// subSet.forEach(System.out::println);
// 返回子SortedSet,从头开始,到参数指定的位置结束。
// 不包括参数指定的位置(终止点)。
SortedSet<Integer> head = set.headSet(8);
// head.forEach(System.out::println);
// 返回子SortedSet,从参数指定的位置开始,到Set结束。
// 包括参数指定的位置(起始点)。
SortedSet<Integer> tail = set.tailSet(3);
tail.forEach(System.out::println);
// 返回最开始的元素(最小的元素)。
System.out.println(set.first());
// 返回最末的元素(最大的元素)。
System.out.println(set.last());
}
}
22、 NavigableSet接口 (NavigableSet接口是SortedSet接口的子接口。扩展了一些导航的方法。可以用于更准确的定位)
package day14;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;
public class NavigableSetMethod {
public static void main(String[] args) {
NavigableSet<Integer> set = new TreeSet<>();
for (int i = 10; i > 0; i--) {
set.add(i);
}
// set.forEach(System.out::println);
// 返回小于参数的最大元素。如果不存在,返回null。
System.out.println(set.lower(-1));
// 返回小于等于参数的最大元素。如果不存在,返回null。
System.out.println(set.floor(5));
// 返回大于等于参数的最小元素。如果不存在,返回null。
System.out.println(set.ceiling(2));
// 返回大于参数的最小元素。如果不存在,返回null。
System.out.println(set.higher(8));
// 删除并返回最开始的元素(最小的元素)。如果没有元素,
// 返回null。
// System.out.println(set.pollFirst());
// 删除并返回最末尾的元素(最大的元素)。如果没有元素,
// 返回null。
// System.out.println(set.pollLast());
// 返回降序排列的NavigableSet
NavigableSet<Integer> de = set.descendingSet();
// de.forEach(System.out::println);
// 返回降序的迭代器
Iterator<Integer> iter = set.descendingIterator();
iter.forEachRemaining(System.out::println);
set.subSet(2, 7);
// 第1个参数:起始点,第3个参数:终止点
// 第2个参数:是否包含起始点。
// 第4个参数:是否包含终止点。
set.subSet(2, true, 7, false);
set.headSet(8);
// 第2个参数指定是否包含终止点。
set.headSet(8, false);
set.tailSet(3);
// 第2个参数指定是否包含起始点。
set.tailSet(3, true);
}
}
23、NavigableSet接口的实现类
TreeSet是AbstractSet的子类,实现NavigableSet 接口。当
向TreeSet中添加元素时,这些元素会自动进行排序。
TreeSet默认情况下使用自然排序,但也可自己制定排序方式。
在创建TreeSet对象时,传递一个实现了Comparator接口的
类的对象。

浙公网安备 33010602011771号