概述
集合
是Java提供的一种容器,可以用来存储多个数据。
与数组的区别:
①数组的长度固定,而集合的长度是可变的
②数组中存储的是同一类型的元素,可以存储基本数据类型,也可以存储对象;而集合存储的都是对象,不能存基本数据类型,但可以把基本数据类型转换成包装类存到集合中,而且对象的类型可以不一致
集合分类
1.单列集合(java.util.Collection)
2.双列集合(java.util.Map)
Collection类下结构图
Collection相关aip
Collection接口中定义着单列集合框架中最最共性的内容,也就是List和Set集合一些通用的方法,这些方法可操作所有的单列集合
1.int size():获取集合长度
2.boolean isEmpty():判断集合是否为空
3.void clear():清空集合
4.boolean contains(Object element):判断当前元素是否在集合内
5.boolean add(Object element):向集合中添加元素
6.boolean remove(Object element):根据参数删除集合中的元素
7.boolean containsAll(Collection c):判断一个集合中的元素是否存在于当前的集合中
8.boolean addAll(Collection c):向一个集合中添加另一个集合
9.boolean removeAll(Collection c):在一个集合中删除参数指定的集合
10.boolean retionAll(Collection c):获取两个集合的交集
11.object[] toArray:把一个集合转换为Object数组
Set接口
1.简介:java.util.Set和java.util.List接口一样,都继承Collection接口,它与Collection接口中的方法基本一致,并没有进行功能上的扩充,只是比Collection接口更加严格了,与List接口不同的是,Set接口中元素无序,并且会已以某种规则保证存入的元素不重复。Set集合取出元素不可以用普通for循环,因为Set集合没有索引,可以采用迭代器或者增强for进行遍历。
HashSet实现类
用hash技术实现的Set结构,也具备集合中元素不能重复这一特性。
1.存入自定义类的时候HashSet如何检查重复:它会根据hashCode来判断对象加入的位置,同时也会与其它已经加入的对象的hashCode进行比较,如果没有相等的hashCode,HashSet就会假设对象没有重复;如果hashCode值相同,会继续使用equals进行比较,如果equals为true,那么认为对象重复了,加入失败。如果为false,那么认为加入的对象没有重复,可以加入。所以我们在自定义类的时候需要重写hsahCode,还要重写equals方法
2.为什么要重写hashCode:因为如果使用Object提供的hashCode方法,他会根据不同的对象生成不同的整数,所以只要创建了不同的对象,hashCode的值是不同的,但如果里面的内容相同,我们就会在集合中存入两个相同内容的元素。为了解决这个问题,我们要重写hashCode方法,让对象具有相同的hashCode值。
@Override
//一般使用idea提供的重写好的hashCode方法,会和equals方法一起重写
public int hashCode() {
return Objects.hash(id, name);
}
3.为什么要重写equals:因为equals比较的是地址,不同对象的地址是不相同的,我们比较的都是内容是否相等,所以想要比较两个对象是否相等,就要重写equals方法,让他按照自己定义的比较方式进行比较两个对象是否相等(一般是比较对象的内容相等)。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student1 student1 = (Student1) o;
//如果id和name都相等,那么两个对象是相同元素
return id == student1.id &&
Objects.equals(name, student1.name);
}
4.当hashCode值相同,equals为false时,元素如何存储?
在同样的哈希值下顺延(放入下一个位置),会用到散列技术等。或者用数组+链表实现;JDK1.8哈希表使用数组加链表加红黑树,当链表长度大于8时,就将链表转换成红黑树,来减少查找到时间。
5.HashSet中存入基本数据类型
//泛型使用基本数据类型的包装类
HashSet<Integer> i = new HashSet<>();
//添加元素
i.add(1);
i.add(2);
System.out.println(i);
6.自定义类型存入HashSet(要在自定义类中重写hashCode和equals方法)
public class Student1 {
private int id;
private String name;
public Student1() {
}
public Student1(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student1{" +
"id=" + id +
", name='" + name + ''' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student1 student1 = (Student1) o;
return id == student1.id &&
Objects.equals(name, student1.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
public static void main(String[] args) {
//创建集合对象 该集合中存储 Student1类型对象
HashSet<Student1> stuSet = new HashSet<Student1>();
//存储
Student1 stu = new Student1("张三", 22);
stuSet.add(stu);
stuSet.add(new Student("李四", 44));
stuSet.add(new Student("张三", 22));
System.out.println(stuSet);//只会存入两个对象
}
LinkedHashSet实现类
因为HashSet保证了元素的唯一,但是元素的存放是无序的,如果我们要保证有序,就要使用LinkedHashSet,他是链表和哈希表组合的一个数据存储结构
public static void main(String[] args) {
//特点是存取有序
Set<String> set = new LinkedHashSet<String>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
Iterator<String> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());//会按顺序打印
}
}
TreeSet实现类
是一个可排序集合,基于红黑树(自平衡二叉树),默认按元素自然顺序升序排列
1.数值类排序
TreeSet<Integer> t = new TreeSet<>();
t.add(3);
t.add(2);
t.add(5);
t.add(1);
t.add(2);
System.out.println(t);//1, 2, 3, 5
2.字符串形式也可排序,会按照第一个字符的升序排列,如果第一个字符相同,按照第二个字符,以此类推。
3.自定义类排序需要使用比较器
比较器
1.Comparable接口:继承接口后在类中重写compareTo方法,让元素自身具备比较性。此接口强行对实现他的每个类的对象进行整体排序,这种排序被称为类的自然排序,类的compareTo方法被称为他的自然比较方法。在创建完该类对象的TreeSet集合后,会自动进行排序。
public class Student implements Comparable<Student> {
private int id;
private String name;
public Student() {
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + ''' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return id == student.id &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public int compareTo(Student o) {
//this 和 参数 o比较
//this>stu (升序排列)
//this<stu (降序排列)
//this等于stu 返回0
//按照id升序排列
// return this.id-o.getId();
//按照id降序排列
// return o.getId()-this.id;
//如果年龄相等的情况下,按照姓名升序排列
int x=this.id-o.getId();
if(x==0){
//按照姓名排序,String内部已经重写ComparTo的方法,这个方法直接返回一个整数
return this.name.compareTo(o.getName());
}else{
return x;
}
}
}
public class Comparable {
public static void main(String[] args) {
TreeSet<Student> stu = new TreeSet<>();
stu.add(new Student(1,"张三"));
stu.add(new Student(4,"李四"));
stu.add(new Student(2,"王五"));
stu.add(new Student(2,"张三"));
//如果按照一个字段进行排序的时候,当前字段在容器中有多个重复的值,那么会认为是重复性元素,只展示一个
//否则如果多个元素作为衡量标准,只要多个元素不重复,就会进行排序。
for(Student s:stu){
System.out.println(s);
}
}
}
2.Comparator接口:元素自身不具备比较性,而让装对象的容器具有比较性。强行对某个对象collection进行整体排序的比较函数。可以将Comparator传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精准控制。
①定义一个类实现Comparator接口,重写compare方法,并将该接口的子类对象作为参数传递给TreeSet集合的构造方法。
public class CompareCollection implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
//按照id升序排列,排序规则和Comparabla的规则一样
return o1.getId()-o2.getId();
}
}
public class Comparator {
public static void main(String[] args) {
Set<Student> stu = new TreeSet<>(new CompareCollection());
stu.add(new Student(1,"张三"));
stu.add(new Student(4,"李四"));
stu.add(new Student(2,"王五"));
stu.add(new Student(2,"张三"));
System.out.println(stu);
}
}
如果对象自身具备比较性,同时容器也具备比较性,那么按照容器的比较性进行比较。
②定义一个类实现Comparator接口,重写compare方法,并将该接口的子类对象作为参数传递给集合的sort方法。
//实现Comparator接口的类同上
public static void main(String[] args) {
List<Student> o = new ArrayList<>();
o.add(new Student(1,"张三"));
o.add(new Student(4,"李四"));
o.add(new Student(2,"王五"));
o.add(new Student(2,"张三"));
o.sort(new CompareCollection());
for(Student s:o){
System.out.println(s);
}
}
List接口
1.List接口的容器类中的元素是有顺序的,而且可以重复,每一个元素都对应一个在容器中位置的序号。
2.List接口中扩展的方法:
①Object get(int index):通过索引获取元素
②Object set(int index,Object element):修改索引出元素
③void add(int index,Object element):在某处索引添加元素
④Object remove(int index):根据索引删除元素
ArrayList实现类
集合数据存储的结构是数组结构,元素增删慢,查找快,因为日常开发中使用最多的功能为查询数据,遍历数据,所以ArrayList是最常用的集合。
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 boolean isEmpty():如果列表不包含元素,则返回truet
ArrayList与LinkedList的区别
1.他们都是线性表,但ArrayList基于数组(顺序存储),LinkedList基于链表(链式存储)
2.由于实现的不同,ArrayList在随机访问元素时性能较高,插入和删除元素时效率较低,LinkedList则反之。
Vector
描述的是一个线程安全的ArrayList。
1.Vector与ArrayList的区别:
ArrayList:多线程效率高
Vector:多线程安全的,所以效率低
2.常用方法:
①void addElement(E obj):在集合末尾添加元素
②E elementAt(int index):返回指定角标的元素
③Enumeration elements():返回集合中的所有元素,封装到Enumeration对象中
Enumeration接口:
①boolean hashMoreElements():测试此枚举是否包含更多元素
②E nextElement():如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
Stack(栈)
Stack类是Vector类的子类,特点是先进后出。
1.常用方法:
①empty():测试堆栈是否为空
②peek():查看堆栈顶部的对象,但不从堆栈中移除他
③pop():移除堆栈顶部的对象,并返回该对象作为此函数的值
④push(E item):把项压入堆栈顶部
⑤int search(Object o):返回对象在堆栈中的位置,以1为基数
操作集合的工具类Collections
用来对集合进行操作
常用方法:
1.sort(List<> list):对List进行默认排序
sort(List<> list,new Comparator(){}):在sort中加入排序器,可以让自定义元素进行排序。
2.addAll(Collection<T>,T…e):向集合中添加可变参数元素
3.fill(List<E> list,E e):将list集合中的所有元素都填充为元素e
4.int frequency(Collection<E> c,E e):返回在集合c中的元素e的个数
5.max,min:获取集合的最大值或者最小值
6.replaceAll(List<E> list, E oldVal, E newVal):将集合list中的所有指定老元素oldVal都替换成新元素newVal
7.reverse(List<E> list):将参数集合list进行反转
8.shuffle(List<E> list):将list集合中的元素进行随机置换
9.swap(List<E> list, int a, int b):将a索引和b索引的元素进行交换
10.synchronizedXxx方法系列:将一个线程不安全的集合传入方法,返回一个线程安全的集合
最后
以上就是勤恳蜜蜂为你收集整理的Java-----Collection集合(hashSet,LinkedHashSet,treeSet,ArrayList,LinkedList)还有比较器的使用详解的全部内容,希望文章能够帮你解决Java-----Collection集合(hashSet,LinkedHashSet,treeSet,ArrayList,LinkedList)还有比较器的使用详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复