集合

mac2025-06-07  56

集合

一、collection接口一)list 有序可重复1.ArrayList方法集合嵌套 2.LinkedList与ArrayList3.for循环遍历list问题 二)set 不可重复重复值问题——重写HashCode 和 equals 方法 二、map接口一)HashMap 无序二)LinkedHashMap 有序三)遍历mapforeach+EntrySet/KeySetiterator+EntrySet/KeySet 四)map的排序 三、collections工具类

一、collection接口

collection接口的子类都有的方法:

add(),无参的添加方法,返回Boolean,表示是否添加成功

一)list 有序可重复

1.ArrayList

方法

方法名参数列表返回值方法含义注意事项---------增-----------add元素eboolean(是否添加成功)添加元素至集合末尾返回值永远为trueadd索引,e添加元素e至集合指定索引位置不会替换掉原来在该索引位置的元素,而是插入这个位置---------删-----------remove索引被删除的元素删除指定索引位置的元素可以用来保存以便利用/归还被删除的元素整数类型集合,当参数放整数时视为下标而不是元素remove元素eBoolean(是否删除成功)删除集合中首次出现的那个元素e只删除首次出现的---------改-----------set索引,e被替换的元素用元素e替换指定索引位置的元素---------查-----------get索引索引位置的元素获得指定位置的元素值---------其他-----------size集合长度获得指定位置的元素值indexOf元素e索引从前往后查找指定元素的第一个下标lastIndexOf元素e索引从后往前查找指定元素的第一个下标---------集合与集合间-----------retainAll集合list2Boolean(对象是否变化)保留对象和参数的交集removeAll集合list2Boolean(对象是否变化)移除对象和参数的交集containsAll集合list2Boolean(是否包含)判断对象是否包含参数中的所有元素忽视下标,只看元素是否相等 数组、集合、字符串的一般规则: 给定元素查找下标,不存在该元素会返回-1;给定下标查找元素,不存在则会报该下标越界异常;

集合嵌套

可以嵌套任何类型(集合套集合、套自定义数据类型、套数组)

嵌套集合后改变小集合内的数据:

向内部的小集合改变元素,一定会改变到大集合,无论此时小集合是否已经被添加至大集合; 因为集合是引用数据类型,操作的是内存中的地址,多层嵌套之后最终指向的还是地址值; 所以只要地址中内容改变,指向该地址的变量都会改变(即最外层的大集合也会改变); public static void main(String[] args) { List<List<String>> list=new ArrayList<>(); List<String> l1=new ArrayList<>(); List<String> l2=new ArrayList<>(); list.add(l1); list.add(l2); l1.add("A"); l1.add("C"); l2.add("D"); System.out.println(list.get(1).get(0));//可以输出D } 嵌套集合的遍历: 嵌套循环(普通for/增强for) public static void main(String[] args) { List<List<String>> list=new ArrayList<>(); List<String> l1=new ArrayList<>(); List<String> l2=new ArrayList<>(); list.add(l1); list.add(l2); l1.add("A"); l1.add("C"); l2.add("D"); l2.add("1"); l2.add("5"); for(int j=0;j<list.size();j++){//普通for for(int i=0;i<list.get(j).size();i++){ System.out.print(list.get(j).get(i)); } System.out.println(); } for(List<String> l:list){//增强for for(String s:l){ System.out.print(s); } System.out.println(); } } //输出都是: //AC //D15

2.LinkedList与ArrayList

用法:一致

类型底层数据结构查找增删应用场景ArrayList数组查找快(有索引)增删慢向数组的指定索引处增加新元素:①创建长度为原数组长度+1的新数组②旧数组中元素依次放置入新数组的0-索引-1③将新元素放入索引值处④将原数组的剩余元素继续依次放入新数组 (直接在尾部追加并不慢)查询动作多的场景,如购物(浏览>增删购物车)、微信(查看好友列表>删除好友添加好友次数)Linkedlist链表查询慢(存储乱)增删快向数组的指定索引处增加新元素:①找到指定位置及其前面的元素②更改2个元素的指向增删动作多的场景

3.for循环遍历list问题

遍历过程:普通for/增强for public static void main(String[] args) { List<String> l1=new ArrayList<>(); l1.add("A"); l1.add("A"); l1.add("B"); l1.add("C"); for(int i=0;i<l1.size();i++){ if(l1.get(i).equals("A")){ l1.remove(i); //i--; //因为删除掉i位置的元素之后,下一个元素就补位到了i位置 //此时i++会直接跳过这个向前补了一位的元素,故当删除了,i就不应该++(用--抵消) } } System.out.println(l1); }

二)set 不可重复

HashSetLinkedHashSetTreeSet底层哈希表(1.7以后哈希表+红黑树)链表+哈希表树是否有序存取无序存取有序存取无序是否可重复不可重复不可重复不可重复性能最优

树 从根节点比较,与当前节点相等放当前节点(覆盖,所以不会重复);比当前节点大放左下边,比当前节点小放右下边

例:一组数据的存储:3 4 11 8 22 4 45 9 6 7

哈希表

数组+链表(1.7以后+红黑树)

添加数据获取数据的哈希值表中是否已有这个哈希值(HashCode≈引用类型在堆中的16进制地址值转换为10进制) 已有:调用equals:true则不再放置(所以不会重复);false则根据算法决定放置位置没有——根据算法决定放置位置

重复值问题——重写HashCode 和 equals 方法

字面值相同但未被去重

场景 由于存储在了2个自定义类型的对象中,地址不同,故哈希值不同; 调用equals时,父类原始equals方法仍只是比较地址值,返回false;

解决

重写HashCode令其return一个固定的int值; 重写equals令其根据自定义类型的某些属性比较

一般先: 判断是否this==参数对象; 判断对象的String类型属性是否有为空的(避免到时候用该属性值调equals,出现空指针异常),若有则直接返回false,若没有则返回其equals比较结果

this.字符属性 == null? false: this.字符属性.getname().equals(obj.getname())

字面值不同但地址相同 哈希冲突,通过带秘钥的哈希函数等方式已被优化

二、map接口

双列的,键不重复,值可以重复,1键只能对应1值

方法名功能返回值参数列表注意事项put在map中存储(或覆盖)键值对的映射关系被覆盖掉的值(如果没有覆盖谁,返回Null)键,值没有任何重载remove模糊删除键值对被删除的值键remove精确删除键值对Boolean键,值需要找到键值都符合参数的键值对才删除,否则不删除replace模糊替换指定键上的旧值被替换的值(null)键,新值:—replace精确替换指定键值对上的旧值Boolean键,旧值,新值需要找到键值都符合参数的键值对才替换,否则不替换get获取指定键上的值值(没有这个键则返回null)键map没有下标概念,只有键entrySet获取集合中的全部键值对关系存放键值对关系的Set集合keySet获取集合中的全部键存放键的Set集合

一)HashMap 无序

二)LinkedHashMap 有序

三)遍历map

遍历方式可应用场景注意事项普通for循环遍历数组、list遍历字符串不可以遍历set、map(因为这两个没有下标)foreach遍历数组、list遍历set不可以遍历字符串、map;只能遍历数组或iterable接口的实例(collection接口继承了iterable接口)foreach+EntrySet/KeySet遍历mapiterator+EntrySet/KeySet遍历map

foreach+EntrySet/KeySet

通过entrySet/keySet方法,获得映射关系的集合/键的集合,遍历返回的集合中的元素,调用get、getKey 和getValue方法获取所有的键和值。

for(int e:people.keySet()){ System.out.print(e+"-"+people.get(e)); } for(Entry<Integer, String> e:people.entrySet()){ System.out.print(e.getKey()+"-"+e.getValue()); }

iterator+EntrySet/KeySet

迭代器iterator 含义:对collection进行迭代的接口 使用对象:collection(不能直接遍历map)

public static void main(String[] args) { Map<String,String> m1=new HashMap<>(); m1.put("AA","123"); m1.put("AB","213"); m1.put("BA","253"); m1.put("BB","423"); Set<Map.Entry<String,String>> s1=m1.entrySet();//获取set集合 Iterator<Map.Entry<String,String>> it=s1.iterator();//获取Set集合的迭代器对象 while (it.hasNext()){ //while的好处:书写方面 //循环条件:有没有下一个元素可获取,没有就结束 System.out.println(it.next());//获取这个"下一个"元素 System.out.println(it.next().getKey()+":"+it.next().getValue()); //执行结果有误,因为每次next,迭代器的指针都会向后移动一位; //故获取的是下一个元素的key和下下个元素的value } for(Iterator<Map.Entry<String,String>> it2=s1.iterator();it2.hasNext();){ //for的好处:it2对象及时释放 System.out.println(it2.next()); } }

迭代器可以 边遍历边删除元素 ! 不能用集合本身进行增删改

集合本身增删改会导致迭代器指向的数据源变化,迭代器发生concurrentModificationException 迭代器的iterator操作的是迭代器副本,不会改变数据源,最后再返回给数据源,故不会异常; 但iterator只有移除功能,如果希望添加(add )可以使用 ListIterator创建Iterator对象; ListIterator有一些返回index、反向遍历previous相关功能; it.next();指针向后移动,移动到下一个元素和下下一个元素之间,返回下一个元素内容 it.previous();指针向前移动,移动到下(前)一个元素和下(前)下(前)一个元素之间,返回下(前)一个元素内容 it.hasprevious();返回Boolean it.hasNext();返回Boolean it.nextIndex();返回int,下一个元素下表 it.PreviousIndex();返回int,上一个元素下标

四)map的排序

map本身是无序的,set(除了linkedhashset)也是无序的,都必须转换成list,然后重写comparable接口的compareTo方法~

Set<String > s1=new HashSet<>(); ArrayList <String> a1=new Arraylist<>(s1); Collections.sort(a1); ----------------------------- Map<String,String> s1=new HashMap<>(); ArrayList<Entry<String,String>> a1= new ArrayList<>(s1.entrySet()); Collections.sort(a1); 调用 entrySet方法 或 keySet方法调用arraylist的构造方法(将set集合作为参数的),创建list对象使用collections工具类的排序方法,将list对象传入,并重写比较器(比较器的参数类型为 Entry<K, V> 或 K)

排序的结果也只能在list中存储和输出,不可能在放回map的,因为map存取无序,排好序放进去的也可能再遍历出来又是底层算法决定的顺序了。

三、collections工具类

方法名功能返回值参数列表注意事项addAll向集合中添加N多数据元素collection集合collection集合,元素1,元素2…reverse倒序排列list类型的集合list集合只有list保证顺序,可以倒序max求最大值集合中数据的类型的排序后的最大值collection类型的集合(数字、字典顺序、ASCII码的顺序)min求最小值同上collection类型的集合(数字、字典顺序、ASCII码的顺序)shuffle打乱list集合list集合replaceAll:—:—:—集合中的东西全部替换掉swap交换集合中2个指定位置的元素list集合list集合,需要交换的下标1,需要交换的下标2sort排序list集合list集合(数字、字典顺序、ASCII码的顺序)clear清空整个集合containsKey判断集合中是否有指定键Boolean键containsValue判断集合中是否有指定的值Boolean值Values获取集合中所有的值集合中的值的类型的集合collection集合不能写collection的子类,除非强转equals比较2个集合元素是否个数、内容完全一致(有序的列表包括顺序一致)Boolean不是比较地址值:----:—:—:—:—:----:—:—:—:—方法名使用场景返回值参数列表其他注意事项compareTocomparable接口的方法,集合的元素之间按属性比较调用sort时可以使用匿名多态写法,创建接口的子类对象并重写compareTo方法,返回排序完成的集合泛型的类型参数降序:返回参数对象.属性-this.属性;升序:返回this.属性-参数对象.属性compareTo字符串之间比较长度一样比较每个字符的字典位置,长度不同比较长度,返回其差值字符串1 ,字符串2compareTo日期之间比较返回日期在参数之前还是之后(-1 0 1)日期对象
最新回复(0)