就业班JavaSE第二阶段第3天
day03 【List、Set、数据结构、Collections】
--数据结构
数据存储的常用数据结构有:
栈: 先进后出,它是受限的线性表,其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作
队列: 先进先出,也是运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除
数组:
查询快--数组的地址是连续的,我们通过数组的首地址可以找到数组,通过数组的索引可以快速查找某一个元素
增删慢--数组的长度是固定的,我们想要增加/删除一个元素,必须创建一个新数组,把原数组的数据复制过来
链表:
查询慢--链表中的地址不是连续的,每次查询元素,都必须从头开始查询
增删快--链表结构,增/删一个元素,对链表的整体结构没有影响,所以增删快
红黑树:
查找速度特别快
--List集合
Lsit接口继承自Collection接口
特点:
有序的集合,存储元素和取出元素的顺序是一致的
有索引,包含了一些带索引的方法
允许存储重复的元素
List接口中带索引的方法(特有)
public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
注意:
操作索引的时候,一定要防止索引越界异常
IndexOutOfBoundsException:索引越界异常,集合会报
ArrayIndexOutOfBoundsException:数组索引越界异常
StringIndexOutOfBoundsException:字符串索引越界异常
package com.itheima.test01;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListTest01 {
public static void main(String[] args) {
//创建List集合
List<String> list = new ArrayList<>();
//public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println(list);//[a, b, c, d],打印的不是地址值,证明List接口重写了toString()方法
//public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
String set = list.set(2, "ithiema");
System.out.println("替换之前的元素:" + set);//替换之前的元素:c
System.out.println("在指定位置添加元素后的集合:" + list);//在指定位置添加元素后的集合:[a, b, ithiema, d]
//public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
String remove = list.remove(3);
System.out.println("移除的元素是:" + remove);//移除的元素是:d
System.out.println("移除指定元素后的集合:" + list);//移除指定元素后的集合:[a, b, ithiema]
//public E get(int index) :返回集合中指定位置的元素。
//遍历集合获取集合中的元素
//普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//迭代器获取集合元素
//创建迭代器对象
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
//增强for循环获取集合元素
for (String s : list) {
System.out.println(s);
}
//数组越界异常:
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(5));//IndexOutOfBoundsException: Index 5 out-of-bounds for length 3
}
}
}
LinkedList集合特点:
是List集合的子类,list接口的方法都可以使用,底层是一个链表结构:查询慢,增删快
里面包含了大量操作收尾元素的方法
注意:
使用LinkdeList集合特有的方法,不能使用多态
特有方法:
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
--Set集合
Set接口继承自Collection接口,无序的集合
特点:
不允许存储重复的元素
没有索引,没有带索引的方法,也不能使用普通for循环遍历
可以使用迭代器和增强for遍历取出元素
HashSet集合:
是Set接口的一个实现类,是根据对象的哈希值来确定元素在集合中的位置
特点:
不允许存储重复的元素
没有索引,没有带索引的方法,也不能使用普通for循环遍历
是一个无序的集合,存储元素和取出元素的顺序可能不一致
底层是一个哈希表结构(查询速度非常快)
哈希值:
是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来的地址,不是实际数据存储的物理地址)
在Object类有一个方法,可以获取对象的哈希值
int hashCode():返回该对象的哈希码值
hashCode方法的源码:
public native int hashCode();
native:代表方法调用的是本地操作系统的方法
HashSet集合存储数据的结构(哈希表):
哈希表=数组+链表
哈希表=数组+红黑树(提高查询的速度)
Set集合不允许存储重复元素的原理:
Set集合唉调用add方法的时候,会调用元素的hashCode方法和equals方法,判断元素是否重复
HashSet存储自定义类型元素:
package com.itheima.test02;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args) {
//HashSet存储自定义类型数据
//没有重写hashCode与equals方法
HashSet<Person> set = new HashSet<>();
set.add(new Person("赵丽颖", 27));
set.add(new Person("赵丽颖", 27));
set.add(new Person("赵丽颖", 30));
System.out.println("没有重写hashCode与equals方法:");
for (Person person : set) {
System.out.println(person);
//所有元素全部添加了进去
/* Person{name='赵丽颖', age=30}
Person{name='赵丽颖', age=27}
Person{name='赵丽颖', age=27}*/
}
HashSet<Person> set1 = new HashSet<>();
set1.add(new Person("杨幂", 37));
set1.add(new Person("杨幂", 37));
set1.add(new Person("杨幂", 40));
//重写了hashCode与equals方法
System.out.println("重写了hashCode与equals方法:");
Iterator<Person> it = set1.iterator();
while (it.hasNext()) {
System.out.println(it.next());
/*Person{name='杨幂', age=40}
Person{name='杨幂', age=37}*/
}
}
}
LinkedHashSet集合:
继承HashSet集合实现Set集合
特点:有序的,不允许存储重复元素
--可变参数
使用前提:
当发放的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型...变量名){}
原理:
可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
传递的参数个数,可以使0个,1,2,3,4...多个
注意事项:
一个方法的参数列表,只能有一个可变参数
如果方法的参数有多个,那么可变参数必须卸载参数列表末尾
--Collections
java.utils.Collections 是集合工具类,用来对集合进行操作。部分方法如下:
public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。
public class CollectionsTest01 {
public static void main(String[] args) {
//public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,2,10,8,5,1,9);
System.out.println(list);
//public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
Collections.sort(list);
System.out.println("排序之后的集合:"+list);//默认升序排列
//public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
Collections.shuffle(list);
System.out.println("打乱顺序之后的集合:"+list);//随机打乱
}
}
使用Comparable进行排序:
import java.util.ArrayList;
import java.util.Collections;
public class ComparableTest01 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Collections.addAll(list, new Student("JAVA", 25),
new Student("C++", 13),
new Student("PHP", 27),
new Student("Python", 19));
System.out.println("未进行排序:" + list);
//如果集合中存储的是自定义的数据类型,想要集合中的元素完成排序,那么必须要实现比较器Comparable接口。
/*
* public class Student implements Comparable<Student>{
...
@Override
public int compareTo(Student o) {
return o.age-this.age;//降序
//return this.age-o.age;//升序
}
}
*/
Collections.sort(list);
System.out.println(list);
}
}
使用Comparator进行排序:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ComparatorTest {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
//向list集合中添加元素
Collections.addAll(list,new Student("Java",30),
new Student("PHP",20),
new Student("C++",40),
new Student("Python",30));
//使用自定义规则对集合中的元素进行排序
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int result = o1.getAge() - o2.getAge();//升序
//return o2.getAge()-o1.getAge();//降序
//如果年龄相同,则比较名字中的首字母
if (o1.getAge()==o2.getAge()){
result = o1.getName().charAt(0) - o2.getName().charAt(0);
}
return result;
}
});
System.out.println(list);
}
}
Comparable和Comparator区别:
Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写比较规则comparaTo方法
Comparator:相当于找一个第三方裁判,比较
|
|