为什么要使用集合类?
集合类就是用于存储多个数据的类 在Java基础中我们学习了数组,而数据时可以存储多个数据的,为什么还要使用集合?
数组的特点
-
用于存放多个数据
-
数组中的数据的数据类型是相同的
-
数组的长度固定
-
数组的操作需要开发人员自己定义相关操作算法
集合类的特点
-
集合类中可以存放多个数据
-
集合类中存放的数据的类型的任意类型(内部类型为Object类型,所以可以存放任意类型)
-
集合类的长度都是可变的
-
集合类中提供了关于这类集合的常用操作方法,开发人员可以通过这些方法实现对集合的常见操作
集合类不是一个类,而是一套接口和类的统称
Java中集合类的类结构
Java中的集合类根据存储方式不同分为两大类集合
-
基于Collection接口的
线性集合Collection接口下有两个子接口,分别对应不同的线性集合
1.List接口的特点
1.有序的集合(进入到集合中顺序) 2.可以存放重复数据的集合
List接口的的实现类:
1.ArrayList 2.LinkedList 3.Vector
2.Set接口
1.无序的集合(不保证集合中元素的顺序) 2.不允许存放重复数据的集合
Set接口的实现类: 1.HashSet 2.TreeSet
-
基于Map接口的
key-value映射对集合
基于List接口的ArrayList类的使用
ArrayList底层是基于动态数组实现的
ArrayList的特点
1.ArrayList在使用时,查找其中的元素效率是比较高的,数组有下标,可以通过下标直接锁定到一个元素
ArrayList在插入或移除元素时效率低(内存中要移位)
ArrayList常用API
-
创建ArrayList对象
//创建ArrayList集合类对象 ArrayList arrayList = new ArrayList();
-
add(element):向ArrayList的尾部追加一个元素
//向ArrayList的尾部追加元素 arrayList.add("aaa"); arrayList.add(20); arrayList.add('a'); arrayList.add(true); arrayList.add(20.5); 3.add(index,element):向集合中的某个位置插入一个元素 //向ArrayList的某个位置插入元素 arrayList.add(2,"str");4.get(index):根据下标获得该下标对应的元素,默认返回Object类型(根据自己的需要转换具体类型)
//根据下标获得一个元素 String str= (String) arrayList.get(0); System.out.println(str);
5.remove(element|index):如果参数为对象类型,则根据内容移除,如果参数为int类型的基本类型则根据下标移除
//移除元素 arrayList.remove("aaa"); System.out.println(arrayList); //如果参数为int类型,则根据下标移除,如果要移除的内容为整数则需要使用Integer类型删除 arrayList.remove(new Integer(3)); ystem.out.println(arrayList);6.遍历ArrayList集合中的所有元素
//遍历List集合中的所有元素
//使用传统for循环遍历
for(int i=0;i<arrayList.size();i++){
Object obj = arrayList.get(i);
System.out.println(obj);
}
System.out.println("---------------");
//使用for循环加强版遍历
for(Object obj : arrayList){
System.out.println(obj);
}
System.out.println("---------------");
//使用list集合中的foreach方法进行遍历
arrayList.forEach(System.out::println);
基于List接口的实现类LinkedList
LinkedList的特点
LinkedList底层是基于链表实现
1.插入或删除元素时效率高 2.查询及遍历元素时效率低
LinkedList常用PAI
add(element):尾部添加
addFirst(element):首部插入
addLast(element):尾部插入
add(index,element):指定下标位置插入元素
push(element):入栈
pop():出栈
toArray():将列表转换为数组
基于List接口的实现类Vector
Vector的特点
1.Vector的底层也是基于动态数组实现 2.Vector中提供的操作和ArrayList基本相同
ArrayList和Vector的区别
-
相同点:ArrayList和Vector底层都是基于动态数组实现,而且提供了相近的API
-
不同点: (1) ArrayList默认创建长度为0的数组,而Vector创建的长度为10的数组 (2) Vector是线程安全的,而ArrayList是非线程安全的,在并发情况下建议使用Vector 我们可以通过外部手段让ArrayList也是线程安全的
基于Set接口的实现类HashSet
HashSet的特点 :
1.底层基于Map集合的实现
2.不能存放重复数据
3.集合中的元素不保证顺序
4.Set集合无法从集合中直接获取某一个元素
5.Set集合没有下标
HashSet常用API 1.add(element):向集合中添加一个元素 2.iterator():遍历集合中的所有元素
//遍历集合中元素
Iterator<String> iterator = hashSet.iterator();
//循环遍历集合中的每个元素
while(iterator.hasNext()){//检测集合中是否存在要迭代的数据,true表示存在
String str = iterator.next();//获取一个元素
System.out.println(str);
}
3.通过foreach循环遍历集合中所有元素
//使用foreach遍历集合中的所有元素
for(String str : hashSet){
System.out.println(str);
}
4.使用foreach方法遍历集合中的元素
//通过foreach方法遍历集合中的所有元素 hashSet.forEach(System.out::println);
基于Set接口的TreeSet实现
TreeSet是基于树状结构的Set集合,该集合可以排序,被称为可排序的Set集合
TreeSet集合的特点 1.TreeSet是一个有序的Set集合 2.TreeSet中不能存放重复数据 3.在TreeSet中存储的元素必须为可排序的元素(实现了比较器接口的对象),如果存储的元素为不可排序的元素则会报异常(ClassCastException)
基于key-value(键值对)的Map集合
Map集合中存储的元素为一个key对应一个value
Map集合的特点
1.key不允许重复,默认情况下key是Object类型,可以存放任意类型的数据 2.value是允许重复,默认情况下value是Object类型,可以存放任意类型的数据 3.Map中允许存在null的key(只能出现一次)和null的value
基于Map接口的实现类HashMap
HashMap中不允许存放重复key,如果新添加的key已存在,则使用新的value替换原有的value值
HashMap的常用API
1.put(key,val):向Map集合中添加一对key-value 2.get(key):根据key获得对应的value 3.remove(key):根据key移除Map集合中的一个元素 4.size():获得集合中元素的数量 5.keySet():获得Map集合中所有的key,返回一个包含所有key的set集合
Map<String,String> map = new HashMap<String,String>(){{
put("key1","val1");
put("key2","val2");
put("key3","val3");
put("key4","val4");
put("key5","val5");
}};
//获得所有的key
Set<String> keySet = map.keySet();
//使用keySet遍历Map集合
Iterator<String> it = keySet.iterator();
while(it.hasNext()){
String key = it.next();
String value = map.get(key);
System.out.println(key+"<---->"+value);
}
6.values():获得Map集合中所有的value,返回一个Collection集合 7.entrySet():获得Map集合中每个元素的Entry集合对象,返回Set集合
for (Map.Entry<String,String> entry : map.entrySet()){
System.out.println(entry.getKey()+"<--->"+entry.getValue());
}
Map集合中的key不能重复,如果想Map添加一个新元素,Map集合如何判定该元素在集合中是否存在?
基于Map接口的TreeMap实现类
TreeMap和TreeSet一样都是一个可排序的集合 TreeMap中根据key进行排序的 进入到TreeMap中的元素(key)必须为可排序的元素(key) ###equals方法 ==也是用于判断两个对象是否相等:用于判断两个对象是否为同一个对象的 equals方法用于判断两个对象的值是否相等
String s1 = "abc";
String s2 = "abc";
//s1和s2两个变量都指向“abc”字符串对象,他们两个是同一个对象
System.out.println(s1 == s2);
/**
* Java中每次使用new关键字创建对象时,在JVM的堆区都会自动创建一个新对象
* 只不过两个对象的值都是"abc"字符串
* 这两个对象不是同一个对象,但他们的值是相等
* 所以“==”的结果为false,他们两个不是同一个对象
* 如果要判断两个对象的值是否相等使用equals方法
*/
String str = new String("abc");
String str1 = new String("abc");
System.out.println(str == str1);//false
System.out.println(str.equals(str1));
equals方法在任意对象中都存在,该方法在Object类中定义的,他们默认定位为
public boolean equals(Object obj) {
return this == obj;
}
从Object类中的源码可以看出,equals方法默认的定义为判断两个对象是否为同一个对象的 所以为了能够判断两个对象的值是否相等,我们在自己定义的实体类中都会重写该方法 String重写equals方法,JDK中大多数类都重写了该方法...
hashCode方法
hashCode方法在任意类中都存在,该方法也是在Object类中定义的 hashCode方法用于获得当前对象所对应的内存地址的hash码 如果两个对象的hash相等,则表示当前的两个对象肯定为同一个对象(默认情况) 开发人员可以根据实际需要重写hashCode,重写后不同对象的hashCode就有可能相等
在开发中一般会重写equals方法和hashCode方法以改变他们的默认行为
Map集合如何判断新添加的元素的key在集合中是否存在
1.先判断hashCode是否相等,如果hashCode不相等则认为没有相同的对象,直接将新元素添加到map集合中 2.如果hashCode的值存在相等的,则无法确定是否存在相同对象,进而继续判断equals方法,如果equals返回值为true,则认为存在相等元素 使用新元素替换原有的元素,如果equals判断是不相等,则认为不存在相同对象直接将新元素添加到map集合中
比较器接口
比较器是用于定义比较规则,有了比较规则后,就可以对这些数据按照比较规则进行排序 Java中定义比较规则的方式有两种:
(1) 实现Comparable接口:Comparable在java.lang包下 - Comparable用于实现对象的默认比较规则,默认比较规则只有一种 - Comparable中存在一个compareTo方法,该方法用于定义比较规则 - 方法的返回值为正整数表示当前对象大于比较对象 - 方法的返回值等于0两个对象相等 - 方法的返回值为负整数表示当前对象小于比较对象
@Override
public int compareTo(User user) {
return this.userId - user.getUserId();
}
(2) 实现Comparator接口:Comparator在java.util包下 - Comparator用于定义对象的扩展比较规则的,可以定义多个 - Comparator接口中有一个定义比较规则的方法compare(obj1,obj2) - 方法的返回值为正整数表示obj1大于obj2 - 方法的返回值等于0两个对象相等 - 方法的返回值为负整数表示obj1小于obj2
/**
* 使用内部类定义扩展规则
* 1.根据积分升序排序
*/
static class sortByScoreASC implements Comparator<User>{
@Override
public int compare(User user1, User user2) {
return user1.getUserScore() - user2.getUserScore();
}
}
/**
* 2.根据积分降序排序
*/
static class sortByScoreDESC implements Comparator<User>{
@Override
public int compare(User user1, User user2) {
return user2.getUserScore() - user1.getUserScore();
}
}
/**
* 2.根据学号降序排序
*/
static class sortByUserIdDESC implements Comparator<User>{
@Override
public int compare(User user1, User user2) {
return user2.getUserId() - user1.getUserId();
}
}
//调用
TreeSet<User> users = new TreeSet<>();//使用user对象中的默认排序规则进行排序
//使用User内定义的内部类指定排序规则
TreeSet<User> users = new TreeSet<>(new User.sortByUserIdDESC());
//使用匿名内部类定义排序规则
TreeSet<User> users = new TreeSet<>(new Comparator<User>() {
//使用匿名内部类实现比较器接口
@Override
public int compare(User user1, User user2) {
return user1.getRegDate().compareTo(user2.getRegDate());
}
});
Java集合类详解:ArrayList, LinkedList, HashSet, TreeSet与Map实现
本文介绍了Java集合类的重要性,对比了数组和集合类的特点。详细讲解了基于Collection接口的ArrayList、LinkedList、Vector,基于Set接口的HashSet和TreeSet,以及基于Map接口的HashMap和TreeMap的使用,包括它们的底层实现、特点、常用API。此外,还讨论了equals方法、hashCode方法和比较器接口在集合类中的作用。
344

被折叠的 条评论
为什么被折叠?



