java集合重难点
一、LinkedList集合
java.util.LinkedList集合是java.util.List的实现类,实现List接口的所有方法(添加,删除,查找,判断是空等) ,它添加,删除元素较快,查询相对慢,但是查询头尾元素较快
LinkedList集合实现双向链表接口,实现从头元素到尾元素的链表和从尾到头元素的链表,目标为了增加元素的检索效率 。
关于LinkedList实现大量操作头元素和尾元素的方法。 其中必须通过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。
二、set集合
java.util.Set 接口 继承自Collection接口,实现对元素的基本操作 ,与java.util.List区别于 Set集合存储无序,且唯一的元素,List存储有序,且可重复的元素
Set接口的实现类 HashSet 、 LinekedHashSet 、TreeSet
1、HashSet
HashSet集合依据元素的哈希值确定在内存中的存储位置, 所谓Hash值是内存中哈希表的唯一标志,通过哈希值可快速检索到元素所在的位置 , 所以它查询效率高 ,与HashSet类似结构的包括HashMap 等
创建一个HashSet时,就是创建一个HasMap( 关于HashMap结构后面讲)
什么是哈希表?
在Java1.8以前,哈希表的底层实现采用数组+链表结构,但是这样对于“Hash冲突” (两个对象生成的哈希值一样),即多个元素存储在一个“数据桶”中, 这样查找该元素时,依然效率低下, 为了解决由于哈希冲突导致的数据查询效率低下,JDK8以后将哈希表实现采用 数组+链表+红黑树结构
1.2.HashSet存储自定义对象类型
HashSet对于对象是否相同的依据,判断对象的hashCode值和equals是否相等,如果它们相等则判断元素一致,不能重复添加
public class People {
private int pid;
private String pname;
private int age;
public People(int pid, String pname, int age) {
this.pid = pid;
this.pname = pname;
this.age = age;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
return this.pid;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof People){
People p = (People) obj;
if(p.pid == this.pid && p.getPname().equals(p.getPname())){
return true;
}
}
return false;
}
}
//存储 对象类型
Set<People> sets = new HashSet<>();
People p = new People(1001,"关羽",100);
People p2 = new People(1002,"张飞",100);
People p3 = p2;
System.out.println("p的hashcode:"+p.hashCode());
sets.add(p);
// 检查是否为同一个地址
sets.add(p);
sets.add(p2);
sets.add(p3);
// 插入一个重新new的张飞对象 HashSet以 equals和hashcode的结果作为是否重复对象的依据
People p4 = new People(1002,"张飞",90);
sets.add(p4); // 会当做是重复的对象 ,不能添加成功。
System.out.println("sets的长度:"+sets.size());
for(People obj : sets){
System.out.println(obj.getPid()+"---"+obj.getPname()+"---"+obj.getAge());
}
1.3 LinkedHashSet
在HashSet中存储的数据是唯一且无序,如何保证数据的有序型,可通过扩展HashSet的子类完成,
java.util.LinkedHashSet ,它实现有序的Hash结构, 它的底层实现使用链表+哈希结构,
创建LinkedHashSet时,就是创建一个LinkedHashMap结构 ,linkeHashSet中如何保证顺序一致性
accessOrder = false; 按照插入的顺序存储 accessOrder = true: 按照访问的顺序存储。
// 创建LinkedHashSet对象
LinkedHashSet<String> set = new LinkedHashSet();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
//遍历元素
for(String s : set){
System.out.println(s);
}
1.4 TreeSet
TreeSet实现对Set元素的排序功能, 也包含基础的Set集合功能。 存放在TreeSet中的元素时有序的,默认升序,也可以自定义排序规则。
两种方式实现自定义排序规则
1、对元素(自定义类)实现 java.lang.Comparable 接口,重写 compareTo方法
public class Fruit implements Comparable<Fruit>{
private int id;
private String name;
public int compareTo(Fruit o) {
// return this.id-o.id; 升序
return o.id - this.id;
// 正数: 前一个大于后一个
// 负数: 前一个小于后一个
}
}
// 实现自定义排序规则的方式一 : 对象实现Comparable接口 (java.lang)
// 重写compareTo 方法。
TreeSet<Fruit> fruitSet = new TreeSet<>();
Fruit f1 = new Fruit(100,"苹果");
Fruit f2 = new Fruit(101,"香蕉");
fruitSet.add(f1);
fruitSet.add(f2);
System.out.println(fruitSet.size());
for(Fruit f : fruitSet){
System.out.println(f.getId()+"---"+f.getName());
}
2、通过匿名内部类的方式 在创建TreeSet时,创建自定义排序规则 ,new Comparator的接口
// 自定义排序规则的方式二: 对treeSet实现匿名内部类 new Comparator(java.util)
TreeSet<Integer> scores = new TreeSet (new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1; //降序
}
});
// 添加元素
scores.add(80);
scores.add(87);
scores.add(90);
scores.add(78);
for(Integer score : scores){
System.out.println(score);
}
// 按照对象的某一属性降序
TreeSet<People> peopleSet = new TreeSet<>(new Comparator<People>() {
@Override
public int compare(People o1, People o2) {
return o2.getAge()- o1.getAge(); // 根据age降序排列
}
});
peopleSet.add(new People(1001,"张飞",100));
peopleSet.add(new People(1002,"刘备",102));
peopleSet.add(new People(1003,"关羽",108));
for(People p : peopleSet){
System.out.println(p.getPid()+"--"+p.getAge());
}