目录标题
数据结构_栈
数据结构_队列
数据结构_数组
查询块:因为通过地址值查找内容
增删慢:因为增删操作会频繁的创建新的数组
数据结构_链表
数据结构_红黑树
List接口
Collection接口子接口List接口
List接口的特点:
1.有序的集合,存储元素和取出元素的顺序是一致的(存储123 取出123)
2.有索引,包含了一些带索引的方法
3.允许存储重复的元素
List接口带的特有方法
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class t1 {
public static void main(String[] args) {
//创建一个List集合对象
List<String> list = new ArrayList<>();
list.add("a");
list.add("c");
list.add("d");
list.add("e");
System.out.println(list);//[a, c, d, e]
//在c和d之间添加一个ityu
list.add(3,"ityu");
System.out.println(list);//[a, c, d, ityu, e]
//移除指定位置元素
String removeE = list.remove(2);
System.out.println(list);//[a, c, ityu, e]
//指定位置替换元素
String setE = list.set(3,"A");
System.out.println(list);//[a, c, ityu, A]
//List集合遍历有3中方式
//普通for
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
//使用迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()){
String next = it.next();
System.out.println(next);
}
//增强for循环
for (String s : list) {
System.out.println(s);
}
}
}
注意事项:
操作索引的时候,一定要防止索引越界异常
IndexOutOfBoundException索引越界异常
ArrayOutOfBoundException数组索引越界异常
StringIndexOutOfBoundException字符串索引越界异常
Arraylist集合
List接口的实现类
ArrayList源码
使用场景
ArrayList底层数组结构,结构特点就是查询比较快,但是增删慢
LinkedList集合
List接口的实现类
LinkedList集合的特点:
1.底层是一个链表结构:查询块,增删慢
2.里面包含了大量操作首尾元素的方法
注意:使用LinkedList特有方法,不能使用多态
使用场景
LinkedList底层是通过链表实现,结构特点是查询慢,增删快
LinkedLIst接口特有的方法
import java.util.LinkedList;
public class t1 {
public static void main(String[] args) {
}
private static void show03() {
LinkedList<String> linked = new LinkedList<>();
linked.add("a");
linked.add("b");
linked.add("c");
String first = linked.removeFirst();
String last = linked.removeLast();
System.out.println(linked);//[b]
}
private static void show02() {
LinkedList<String> linked = new LinkedList<>();
linked.add("a");
linked.add("b");
linked.add("c");
linked.clear();//清空集合中的元素
if (!linked.isEmpty()){
String first = linked.getFirst();
String last = linked.getLast();
System.out.println(first);//a
System.out.println(last);//c
}
}
private static void show01() {
//创建LinkedList集合对象
LinkedList<String> linked = new LinkedList<>();
//使用add方法添加元素
linked.add("a");
linked.add("b");
linked.add("c");
//addFirst此方法等效于push
linked.addFirst("www");
System.out.println(linked);//[www, a, b, c]
//addList()此方法等效于add()
linked.addLast("com");
System.out.println(linked);
}
}
Vector集合(了解即可)
set接口的实现类HashSet集合
set接口的特点
1.不能存储重复元素
2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
set接口实现类HashSet特点
1.不能存储重复元素
2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
4.底层是一个哈希表结构(查询的速度非常快)
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class t1 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(3);
set.add(2);
set.add(1);
//迭代器遍历
Iterator<Integer> it = set.iterator();
while (it.hasNext()){
Integer next = it.next();
System.out.println(next);//1 2 3 不允许存储重复元素
}
//也可以使用增强for
for (Integer integer : set) {
System.out.println(integer);
}
}
}
哈希表
哈希值:
是一个十进制的整数,由系统随机给出
在Object类有一个方法,可以获取对象的哈希值hashCode()返回对象的哈希码
hashCode()源码
native:代表该方法调用的是本地操作系统的方法
Set集合存储元素不重复的原理
Set集合在调用add方法的时候,add方法会调用元素的hashCode方法(重写hashCode对于相同的内容会生成相同的哈希值比较哈希地址是否相同)和equals方法(通过重写从比较地址值改为:比较内容是否相),通过两个判读来判断元素是否重复.
打一个简单的例子:同名称(equals)和同年龄(hasCode)的我,我们就视为同一人,只能存储一次
"重地"和"通话"重写后的哈希值完全相同是纯属巧合
HashSet存储自定义类型元素
创建自定义的Person类
import java.util.Objects;
public class Person extends Object{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.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);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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;
}
}
主程序
import java.util.HashSet;
public class t1 {
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("玛雅战记",18);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(p1.hashCode());//-988359734
System.out.println(p2.hashCode());//-988359734
System.out.println(p2.equals(p1));//true
System.out.println(p1==p2);//false
}
}
注意事项:
Set接口下实现类的存储自定义元素,必须重写hashCode方法和equals方法
HashSet集合子类LinkedHashSet集合
LinkedHashSet集合特点:
底层是一个哈希表(数组+红黑树)+链表:多了一条链表(记录元素存储顺序),保证元素有序
package test.code.src.cn.itcast.day11.demo08;
import java.util.HashSet;
import java.util.LinkedHashSet;
public class t1 {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("www");
set.add("abc");
set.add("abc");
set.add("ityu");
System.out.println(set);//[abc, www, ityu]无序,不允许重复
LinkedHashSet<String > linked = new LinkedHashSet<>();
linked.add("www");
linked.add("abc");
linked.add("abc");
linked.add("itcast");
System.out.println(linked);//[www, abc, itcast]
}
}
可变参数
使用场景:
当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
使用格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型...变量名){}
可变参数的原理:
可变参数的底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
public class t1 {
public static void main(String[] args) {
int add = add(10,20,30);
System.out.println(add);
}
public static int add(int ...arr){
int sum = 0;
for (int i : arr) {
sum += i;
}
return sum;
}
}
注意事项:
1.一个方法的参数列表,只能有一个可变参数
2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾