目录
常见的数据结构
数据存储的常用结构有:栈、队列、数组、链表和红黑树。
栈
栈:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作, 不允许在其他任何位置进行添加、查找、删除等操作。
简单的说:采用该结构的集合,对元素的存取有如下的特点:先进后出.栈的入口、出口的都是栈的顶端位置。
压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位 置。
弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。
队列
队列:queue,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,在另一端进行删除。
特点:先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。
数组
数组:Array,是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素
特点:查找元素快:通过索引,可以快速访问指定位置的元素
增删元素慢:指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原 数组元素根据索引,复制到新数组对应索引的位置。如下图
链表
链表:linked list,由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时i动 态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的 指针域。我们常说的链表结构有单向链表与双向链表
特点:查找元素慢、增删元素快
红黑树
二叉树binary tree
每个结点不超过2的有序树(tree)。
- 1.节点可以是红色的或者黑色的
- 2.根节点是黑色的
- 3.叶子节点(特指空节点)是黑色的
- 4.每个红色节点的子节点都是黑色的
- 5.任何一个节点到其每一个叶子节点的所有路径上黑色节点数相同
List集合
java.util.List接口继承自Collection 接口,是单列集合的一个重要分支,习惯性地会将实现了 List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行 存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。
1.元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就 是按照11、22、33的顺序完成的)。
- 2.它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
- 3.集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素
List接口中常用方法
列:List接口常用方法练习
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("老赵");
list.add("老王");
list.add("老孙");
list.add("老李");
list.add("老赵");//list可以添加重复数据
System.out.println(list);//[老赵, 老王, 老孙, 老李, 老赵]
//1 public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
list.add(1,"老周");
System.out.println("1 根据索引添加数据:"+list);//根据索引添加数据:[老赵, 老周, 老王, 老孙, 老李, 老赵]
//2 public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
String remove = list.remove(4);
System.out.println("2 根据索引移出数据:"+remove+"\t"+list);
//3 public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
String setList = list.set(1, "王老师");
System.out.println("3 根据索引修改数据:"+setList+"\t"+list);
//4 集合遍历-方法1:普通for循环
System.out.print("4 集合遍历-方法1:普通for循环:");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i)+"-");
}
//5 集合遍历-方法2:增强for循环
System.out.print("\n5 集合遍历-方法2:普通for循环:");
for (String s : list) {
System.out.print(s+"~");
}
//6 集合遍历-方法3:迭代器
System.out.print("\n6 集合遍历-方法3:迭代器:");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String next = it.next();
System.out.print(next+"-");
}
}
结果:
ArrayList集合
java.util.ArrayList集合数据存储的结构是数组结构。元素查找快、增删慢,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。
LinkedList集合
java.util.LinkedList集合数据存储的结构是链表结构。元素查询慢、增删快

- public void addFirst(E e):将指定元素插入此列表的开头。
- public void addLast(E e):将指定元素添加到此列表的结尾。
- public E getFirst():返回此列表的第一个元素。
- public E getLast():返回此列表的最后一个元素。
- public E removeFirst():移除并返回此列表的第一个元素。
- public E removeLast():移除并返回此列表的最后一个元素。
- public E pop():从此列表所表示的堆栈处弹出一个元素。
- public void push(E e):将元素推入此列表所表示的堆栈。
- public boolean isEmpty():如果列表不包含元素,则返回true。
列: LinkedList类常用方法练习
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("老赵");
linkedList.add("老钱");
linkedList.add("老孙");
linkedList.add("老赵");//可以添加重复数据
System.out.println("原LinkedList是:" + linkedList);
demo01(linkedList);
demo02(linkedList);
demo03(linkedList);
}
/* 3
- public E removeFirst():移除并返回此列表的第一个元素。
- public E removeLast():移除并返回此列表的最后一个元素。
- public E pop():从此列表所表示的堆栈处弹出一个元素。此方法相当于 removeFirst
*/
private static void demo03(LinkedList<String> linkedList) {
//3.1 public E removeFirst():移除并返回此列表的第一个元素。
String remove = linkedList.remove();
System.out.println("3.1 移出第一个元素:"+remove+"\t"+linkedList);
//3.2 public E removeLast():移除并返回此列表的最后一个元素。
String s = linkedList.removeLast();
System.out.println("3.2 移出最后一个元素:"+s+"\t"+linkedList);
//3.3 public E pop():从此列表所表示的堆栈处弹出一个元素。此方法相当于 removeFirst
String pop = linkedList.pop();
System.out.println("3.3 移出第一个元素:"+pop+"\t"+linkedList);
}
/* 2
- public E getFirst():返回此列表的第一个元素。
- public E getLast():返回此列表的最后一个元素。
*/
private static void demo02(LinkedList<String> linkedList) {
//linkedList.clear();//清空集合中的元素 在获取集合中的元素会抛出NoSuchElementException
if (!linkedList.isEmpty()){ // //public boolean isEmpty():如果列表不包含元素,则返回true。
//2.1 public E getFirst():返回此列表的第一个元素。
String first = linkedList.getFirst();
System.out.println("2.1 返回此列表的第一个元素:"+first+"\t"+linkedList);
//2.2 public E getLast():返回此列表的最后一个元素。
String last = linkedList.getLast();
System.out.println("2.2 返回此列表的最后一个元素:"+last+"\t"+linkedList);
}
}
/* 1
- public void addFirst(E e):将指定元素插入此列表的开头。
- public void addLast(E e):将指定元素添加到此列表的结尾。
- public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于 addFirst(E)。
*/
private static void demo01(LinkedList linkedList) {
//1.1 public void addFirst(E e):将指定元素插入此列表的开头。
linkedList.addFirst("姓名");
System.out.println("1.1 在集合前添加数据:"+linkedList);
//1.2 public void addLast(E e):将指定元素添加到此列表的结尾。
linkedList.addLast("结尾");
System.out.println("1.2 在集合后添加数据:"+linkedList );
//1.3 public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于 addFirst(E)。
linkedList.push("aaaa");
System.out.println("1.3 在集合前添加数据:"+linkedList);
}
结果:
Set集合(接口 )
java.util.Set 接口继承自Collection 接口。Set 接口中元素无序
Set集合有多个子类,这里我们介绍其中的java.util.HashSet、java.util.LinkedHashSet 这两 个集合。
HashSet集合介绍
java.util.HashSet是Set接口的一个实现类,它所存储的元素是不可重复的且是无序的(即存取顺序不一致)。
HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性的方式依赖于:hashCode与equals方法。
哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树

列:set集合练习
public class Demo01Set {
public static void main(String[] args) {
Set<Integer> set=new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
set.add(1);//set不允许存重复数据
System.out.println(set);
//1 增强for遍历
System.out.print("1 增强for遍历:");
for (Integer integer : set) {
System.out.print(integer+"-");
}
//2 迭代器遍历set集合
System.out.print("\n2 迭代器遍历:");
Iterator<Integer> it = set.iterator();
while (it.hasNext()){
Integer next = it.next();
System.out.print(next+"~");
}
}
}
结果:
列:HashSet存储对象
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)
对象重写equals() 、HashCode()方法
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
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 "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public static void main(String[] args) {
HashSet<Person> set=new HashSet<>();
Person p1=new Person("小美女",18);
Person p2=new Person("小美女",18);
Person p3=new Person("小美女",19);
System.out.println(p1.hashCode()+"\n"+p2.hashCode()+"\n"+p3.hashCode());
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set);
}
结果:
LinkedHashSet
LinkedHashSet集合特点: 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序
java.util.LinkedHashSet是HashSet的子类,它是链表和哈希表组合的一个数据存储结构,存储的元素有顺序
列:HashSet与LinkedHashSet的遍历
public class Demo04LinkedHashSet {
public static void main(String[] args) {
HashSet<String> set=new HashSet<>();//HashSet数据无顺序且不重复
set.add("www");
set.add("123");
set.add("123");
set.add("lws");
System.out.println(set);//[123, www, lws]
LinkedHashSet<String> linkedHashSet=new LinkedHashSet<>();//LinkedHashSet数据有顺序且不重复
linkedHashSet.add("www");
linkedHashSet.add("123");
linkedHashSet.add("123");
linkedHashSet.add("lws");
System.out.println(linkedHashSet);//[www, 123, lws]
}
}
可变参数
定义一个方法需要接受多个参数,并且多个参数类型一致
列:使用可变参数方法实现n个数相加,n个字符串拼接
public class Demo01VarArgs {
public static void main(String[] args) {
add(1, 2, 3);
String a1 = new String("Hello ");
String a2 = "world ";
String a3 = "welcome ";
stringConant(a1, a2, a3);
}
/*
可变参数的注意事项
1.一个方法的参数列表,只能有一个可变参数
2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
*/
public static void add(int... arr) {
int sum = 0;
for (int i : arr) {
sum = i + sum;
}
System.out.println(sum);
}
/*
n个字符串拼接
*/
public static void stringConant(String... str) {
String a = "";
for (String s : str) {
a += s;
}
System.out.println(a);
}
}