集合

一、collection接口

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

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

一)list 有序可重复

1.ArrayList

方法
方法名参数列表返回值方法含义注意事项
---------增-----------
add元素eboolean(是否添加成功)添加元素至集合末尾返回值永远为true
add索引,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遍历map
iterator+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);
  1. 调用 entrySet方法 或 keySet方法
  2. 调用arraylist的构造方法(将set集合作为参数的),创建list对象
  3. 使用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,需要交换的下标2
sort排序list集合list集合(数字、字典顺序、ASCII码的顺序)
clear清空整个集合
containsKey判断集合中是否有指定键Boolean
containsValue判断集合中是否有指定的值Boolean
Values获取集合中所有的值集合中的值的类型的集合collection集合不能写collection的子类,除非强转
equals比较2个集合元素是否个数、内容完全一致(有序的列表包括顺序一致)Boolean不是比较地址值
:----:—:—:—:—
:----:—:—:—:—
方法名使用场景返回值参数列表其他注意事项
compareTocomparable接口的方法,集合的元素之间按属性比较调用sort时可以使用匿名多态写法,创建接口的子类对象并重写compareTo方法,返回排序完成的集合泛型的类型参数降序:返回参数对象.属性-this.属性;升序:返回this.属性-参数对象.属性
compareTo字符串之间比较长度一样比较每个字符的字典位置,长度不同比较长度,返回其差值字符串1 ,字符串2
compareTo日期之间比较返回日期在参数之前还是之后(-1 0 1)日期对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值