Java集合概述
一、集合的分类
-
蓝色为接口,后面的为具体的实现类
-
单列:
张三 李四 王二 -
双列:
name 张三 name 李四 name 王二
二、集合的使用
- 集合是用于储存数据,但是不包括基本类型,基本类型需要使用他们的包装类
- 集合一般使用多态的方式,用其子类的具体类去实现
- 集合中各实现类一般都会重写toString方法,直接输出对象即可得到内容
三、Collection集合常用方法
// 因为Collection为接口,所以使用他的实现类通过多态的方式实例化对象
Collection<String> c = new ArrayList<String>();
// 添加集合内容 boolean add()
c.add("hello");
// 删除集合中指定内容 boolean remove() ,若元素不存在返回值为false
c.remove("hello");
// 清空集合中的元素 void clear()
c.clear();
// 判断集合中是否存在指定元素 boolean contains()
c.contains("hello");
// 判断集合是否为空 boolean isEmpty()
c.isEmpty();
// 得到集合的长度 int size()
c.size();
// Collection 三种遍历方式
// 1、使用对象中的iterator方法得到迭代器,使用迭代器循环时,不可以在循环体内部进行数据的添加或删除操作,会报错
Iterator<String> it = c.iterator();
// 返回迭代器中的下一个元素 E next();
System.out.println(it.next());
System.out.println(it.next());
// boolean hasNext() 如果迭代器中还有其他元素,则返回为turn
while(it.hasNext()){
String s=it.next();
System.out.println(s);
}
// 2、使用for循环(set集合不可以使用,因为没有索引)
for(int i =0;i<c.size();i++){
String s = c.get(i);
System.out.println(s);
}
// 3、使用增强型for循环
for(String i : c){
System.out.println(i);
}
四、List集合的常用方法
//创建List集合类
List<String> list = new ArrayList<>();
// list.add(int index, Sting s) 超出索引会报错
list.add(1,"city");
// list.remove(int index) 返回被删除的元素
list.remove(2);
// list.set(int index,String s) 修改指定索引的元素,返回修改的元素
list.set(1, "hey");
// list.get(int index) 获取指定索引的元素
list.get(3);
System.out.println(list);
// 可使用以上三种方式遍历内容
五、ListIterator迭代器使用
List<String> list = new ArrayList<>();
// 使用list.listIterator 调出迭代器
ListIterator<String> lit = list.listIterator();
// 使用 lit.next()可以获得下一个值
while(lit.hasNext()){
String s = lit.next();
System.out.println(s);
}
System.out.println("--------------------");
// 使用 lit.previous()可以获得上一个值
while(lit.hasPrevious()){
String p = lit.previous();
System.out.println(p);
}
// 在ListIterator 迭代器中,可以使用迭代器的添加方法在循环中添加元素
while(lit.hasNext()){
String s1 = lit.next();
if (s1.equals("world")){
lit.add("javaooo");
}
}
六、 Arraylist与LinkedList的区别
ArrayList底层是使用数组,LinkedList底层是使用链表。
数据结构基本知识
1、栈结构
-
数据进入过程为:压/进栈
数据出去过程为:弹/出栈
栈结构,数据先进的最后出
2、队列
-
数据进入过程为:入队列
数据出去过程为:出队列
队列结构,数据先进的先出
3、数组与链表的结构特点
-
数组查询数据可以使用索引,查询快,但是在做增删时每一个数据都要重写挪动,修改慢。
-
链表中的元素为结点,结点由数据,地址、下一个数据的地址组成,特点是查询慢,增删快
在修改数据时只需要更改结点对应的下一个或上一个数据地址即可
七、Set集合使用
-
该集合没有索引,不能通过for循环遍历元素
-
该集合不能存储相同的元素,其底层的逻辑为Hash表
-
方法来自Collection
-
HashSet对迭代器的顺序没有保证,即存入和取出顺序不一致
八、Hash值
1.
1. 哈希值就是根据对象的地址或字符串或数字算出来的int类型的数值
2. 默认情况下,除了字符串内容相同时,Hash值相同,其他无特殊的字符。均不相同
3. 通过在对象中对HashCode()方法重写可以实现值相同
2.
- Hash表底层是数组加链表实现,可以说是一个元素为链表的数组,其索引有16
- 集合Set中不能存储相同元素的底层原理是使用了Hash值进行对比,元素Hash值%16为在表中位置,若位置无元素,则直接存储,有元素先比较Hash值,不同就存储,相同再比较内容,不同存储,相同不存储!
九、LinkedHashSet的使用
1.此集合是一个不存储相同元素的有序集合
2.不储存相同元素由Hash表决定
3.有序有链表决定
4.不能使用for循环遍历
十、TreeSet的使用
1.
-
该集合是一个根据特定规定排序的有序集合
// TreeSet中两个构造方法 TreeSet() 无参是根据自然排序 TreeSet(Comparator comparator) 带参是根据指定的比较器进行排序
-
不可储存重复元素
-
不可用for循环遍历
2.
- 使用自然排序构造时,需要在其元素类中继承Comparable接口,重写compareTo(类型 名) 方法
compareTo(T o)
// 将此对象与指定的对象进行比较以进行排序。 返回一个负整数,零或正整数,因为该对象小于,等于或大于指定对象。
public int compareTo(Person p) {
//return 0; //默认后面的元素与前元素相同,则只能显示最先录入的一个元素
//return 1;//返回值为正数时则按照录入的顺序进行排序
//return -1;//返回值为负数时则按照录入的倒序进行排序
/* 需求是按照年龄顺序排列时 this.age为后一个元素,p.getAge为前一个,结果为正数则顺序,负数为倒序
int num = this.age - p.getAge();
return num;*/
/* 当年龄相同但是内容不同时,则需要判断两个对象的姓名的排序:A>Z>a>z
compareTo(T o) :将此对象与指定的对象进行比较以进行排序。 返回一个负整数,零或正整数,因为该对象小于,等于或大于指定对象。
*/
int num = this.age-p.getAge();
int num2 = num==0? this.name.compareTo(p.getName()): num;
return num2;
}
- 使用比较器,也就是带参构造进行比较
/*
使用TreeSet(Comparator o)构造器,传递比较器接口进行比较
*/
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 作比较:主要求按照年龄大小顺序,年龄相同按姓名顺序 s1为后一个对象
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});