文章目录
- Collection-单列集合特点
- List
- ArrayList
- LinkedList
- Vecter
- Set
- HashSet
- TreeSet
- Map-键值对集合特点
- Map常用API
- put添加细节
- remove
- Map的三种遍历方式
- 1.通过键找值
- 2.通过"键值对"
- 3.Lambda表达式
- foreach源码
- HashMap
- 需求
为什么要使用泛型
泛型的优点1.集合中存储的元素类型统一了2.从集合中取出来的元素类型是泛型指定的类型,不需要进行大量的“向下转型”泛型的确定1.导致集合中存储的元素缺乏多样性。
Collection-单列集合特点
List
ArrayList
ArrayList特点1.ArrayList层地采用了数组的数据结构;2.ArrayList是非线程安全的;3.ArrayList初始化容量是10(底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量10);4.ArrayList底层是Object类型的数组Object[]5.扩容1.5倍6.建议给定一个预估计的初始化容量,减少数组的扩容次数,这是ArrayList集合比较重要的优化策略数组的优点1.数组的检索效率比较高。为什么数组的检索效率高?数组中每个元素占用空间大小相同,内存地址是连续的,知道首元素内存地址,然后知道下标,通过数学表达式计算出元素的内存地址,所以检索的效率高。2.数组向数组末尾添加元素的效率还是很高的,也就是数组的添加效率很高。数组的缺点1.数组随机增删元素效率比较低
LinkedList
链表数据结构的特点
链表的优点:1.由于链表上的元素在空间存储上内存地址不连续,所以随机增删元素的时候不会有量元素的位移,因此随机增删的效率高。在以后得开发中,如果遇到随机增删集合中元素的业务比较多时,建议使用LinkedList链表的缺点1.不能通过数学表达式计算被查找元素的内存地址,每一次查找都是从头节点开始遍历,直到找到为止,所以LinkedList集合检索/查找的效率较低。
LinkedList特点1.LinkedList底层采用了双向链表数据结构
Vecter
Vecter特点1.Vector底层也采用了数组的数据结构是线程安全的。2.Vector底层方法都使用了synchronized关键字修饰虽然线程安全但效率不高,一般使用较少了。
Set
HashSet
HashSet特点:1.HashSet创建时实际上是底层new了一个HashMap集合,也就意味着HashSet是将数据存储到了HashMap集合中了,HashMap是一个哈希表数据结构;
TreeSet
TreeSet的父级接口是SortSet,SortSet继承了Set接口,接口是抽象的,无法实例化。
TreeSet特点1.TreeSet也称可排序集合2.无顺不可重复,但存储的元素可以自动按照大小顺序或字幕A~Z排序3.无序:指得是元素存进去的顺序和取出来的顺序不一样,并且没有下标。4.TreeSet创建的时候,底层new了一个TreeMap,TreeMap底层使用了二叉树数据结构
Map-键值对集合特点
Map-键值对集合特点:1.Map是以key(键)和value(值)的方式存储数据:键值对;2.key(键)不能重复,value(值)可以重复;3.key(键)和value(值)都是引用数据类型,存储对象的内存地址;4.key(键)和value(值)一一对应,每一个键只能找到自己对应的值,key起到主导的地位,value是key的一个附属品。5.key(键)和value(值)是一个整体,称为"键值对"或者"键值对对象",在Java中叫做"Entry对象"。
Map常用API
Map接口中常用方法:* V put(K key,V value) 向Map集合中添加键值对* V get(Object key) 通过Key获取value* void clear() 清空Map集合* boolean containsKey(Object key) 判断Map中是否包含某个Key* boolean containsValue(Object value) 判断Map中是否包含某个value* boolean isEmpty() 判断Map集合中元素个数是否为0* Set<K> keySet() 获取Map集合中所有的key(所有的键是一个set集合)* V remove(Object key) 通过key删除键值对* int size() 获取Map集合中键值对的个数* Collection<V> values() 获取Map集合中所有的value,返回一个Collection
代码中选中Map关键字Ctrl+B去到Map的源码中
put添加细节
1.put对象是,Map有返回值
put:添加/覆盖在添加数据的时候,如果键不存在,那么直接把键值对对象提提添加到map集合当中,方法返回null在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回。
public class MapApi {public static void main(String[] args) {Map<String,String> m = new HashMap<>();String value0 = m.put("郭靖","黄蓉");System.out.println(value0);m.put("韦小宝","沐剑屏");m.put("杨过","小龙女");m.put("尹志平","小龙女");//向相同的键里再次添加元素String value = m.put("韦小宝","双儿");System.out.println(value);System.out.println(m);}
}
remove
remove时也有返回值,返回的是被删除的键值对对象的值。
public class MapTest01 {public static void main(String[] args) {Map<Integer,String> map = new HashMap<>();//1.向Map中添加key-valuemap.put(101,"zhangsan");map.put(202,"lisi");map.put(303,"wangwu");map.put(404,"zhaoliu");System.out.println(map);//2.获取添加到Map中的key-value的个数System.out.println("2.Map中所有键值对的个数:"+map.size());//3.通过key取valueString value = map.get(303);System.out.println("3.通过key取到的value为:"+value);//4.获取所有的valueCollection<String> values = map.values();System.out.println("4.values()获取Map中的所有value:"+values);//foreach valuesfor(String str : values){System.out.println("5.遍历取出:"+str);}//6.获取所有的keySet<Integer> keys = map.keySet();System.out.println("6.keySet()返回Map中所有的key:"+keys);//7.判断是否包含某个key和valueSystem.out.println("7.判断是否包含202的key的结果为:"+map.containsKey(202));System.out.println("8.判断是否包含leilei的value的结果为:"+map.containsValue("leilei"));//9.通过key删除key-valuemap.remove(404);System.out.println("9.调用remove()方法后的键值对的数量:"+map.size());//10.清空Map集合map.clear();System.out.println("10.clear()后键值对的数量为:"+map.size());}
}
{404=zhaoliu, 101=zhangsan, 202=lisi, 303=wangwu}
2.Map中所有键值对的个数:4
3.通过key取到的value为:wangwu
4.values()获取Map中的所有value:[zhaoliu, zhangsan, lisi, wangwu]
5.遍历取出:zhaoliu
5.遍历取出:zhangsan
5.遍历取出:lisi
5.遍历取出:wangwu
6.keySet()返回Map中所有的key:[404, 101, 202, 303]
7.判断是否包含202的key的结果为:true
8.判断是否包含leilei的value的结果为:false
9.调用remove()方法后的键值对的数量:3
10.clear()后键值对的数量为:0
Map的三种遍历方式
1.通过键找值
public static void main(String[] args) {Map<String,String> m = new HashMap<>();m.put("郭靖","黄蓉");m.put("韦小宝","沐剑屏");m.put("杨过","小龙女");System.out.println(m);Set<String> keys = m.keySet();for(String str : keys){String key = str;String value = m.get(key);System.out.println(key + "=" + value);}}
2.通过"键值对"
public static void main(String[] args) {Map<String,String> m = new HashMap<>();m.put("郭靖","黄蓉");m.put("韦小宝","沐剑屏");m.put("杨过","小龙女");System.out.println(m);Set<Map.Entry<String, String>> entries = m.entrySet();for (Map.Entry e : entries){System.out.println(e.getKey()+"="+e.getValue());}}
Ctrl+Alt+V自动生成方法的返回值类型,或者在方法名后加.var也可以
3.Lambda表达式
public static void main(String[] args) {Map<String,String> m = new HashMap<>();m.put("鲁迅","我没说过这句话");m.put("诸葛亮","悠悠苍天,何薄于我");m.put("曹操","我笑诸葛无谋,周瑜少智");System.out.println(m);m.forEach(new BiConsumer<String, String>() {@Overridepublic void accept(String s, String s2) {System.out.println(s +"="+s2);}});//改写为lambdam.forEach((s, s2) -> System.out.println("我是lambda:"+s +"="+s2));}
foreach源码
foreach的缺点foreach底层也是使用的增强for循环,它没有下标,不能通过下标查询元素
HashMap
HashMap底层原理1.HashMap底层是哈希表结构2.依赖hashCode方法和equals方法保证键的唯一3.如果键存储的是自定义对象,需要重写hashCode和equals方法如果值存储字定义对象,不需要重写hashCode和equals方法
需求
创建一个HashMap集合,1.键是学生对象(Student),值是籍贯(String).2.存储三个键值对元素,并遍历3.要求:同姓名同年龄认为是同一个学生。
public class Student {private int age;private String name;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age &&Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(age, name);}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +'}';}getter setter省略......
}
public class HashMapTest {public static void main(String[] args) {HashMap<Student,String> map = new HashMap<>();//1.实例化学生对象Student student0 = new Student(23,"张三");Student student1 = new Student(24,"李四");Student student2 = new Student(25,"王五");Student student3 = new Student(25,"王五");map.put(student0,"湖北");map.put(student1,"广东");map.put(student2,"河南");map.put(student3,"福建");//遍历map对象Set<Student> students = map.keySet();for(Student stu : students){String value = map.get(stu);System.out.println(stu +"=>"+value);}}
}