集合
Collection
它是集合框架中的根接口,它提供了对集合进行基本的操作。
- 常用子接口:
- List:有序,可重复的
Set:无序(存取顺序不保证一致),不可重复的
集合又叫集合框架,因为它是一个大的体系。
不是一个类是一个接口。里面有两个子类List和Set实现类,都在util包内。
List常用实现类:
ArrayList
LinkedListSet常用实现类:
HashSet
TreeSet
LinkedHashSet泛型:
在创建集合时,明确集合中存储数据的类型,要指定数据类型。
泛型中不能指定基本数据类型,要指明基本类型对应的包装类。
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
booblean Boolbean
List
集合都是为了存储数据,为了实现增删改查的。分出多种是因为更符合业务,提高效率。比如存储更快更改更快
ArrayList
底层数据结构是数组的一种List集合。
- 常用方法:
- add(e):在集合的末尾添加元素,并返回true (为什么add有返回值,因为这是从父类中重写的,父类有。当时父类是有多个子类,虽然你不需要,但是有人需要。)
- add(index,e):在指定位置上添加元素,无返回(为什么它没有,因为它不是重写的父类,而是重载的add方法,这只属于它自己,它不需要返回值自然不用返回。)
- remove(index):删除指定位置上的元素,返回被删除的元素(对象)。
- remove(object):删除指定元素,如果对象不存在则删除失败返回false
- set(index,e):将新值e替换指定位置上的原始数据,并返回被替换的原始值
- get(index):通过下标获取指定元素
- clear():清空集合
- contains(object):判断集合中是否包含指定元素
- isEmpty():判断集合内容是否为空
- indexOf(object):根据指定元素返回第一次出现的下标,元素不存在返回-1
- lastIndexOf(object):根据指定元素返回最后一次出现的下标,元素不存在返回-1
- size():返回集合的元素个数
- addAll(collection e):将e集合添加到集合的末尾
- addAll(index,collection e):将e集合添加到集合的指定位置
- containsAll(collection e):判断是否包含指定集合中的元素
- removeAll(collection e):从原集合中删除两集合的交集
- retainAll(collection e):将两集合的交集存到原集合中
- equals(collection e):判断两集合的元素是否完全相同(顺序)
有序可重复的。
遍历
for(int i=0;i<list.size(),i++){ //list.get(i); }
嵌套
将集合作为另一个集合的子元素。
LinkedList
底层的数据结构是链表
LinkedList:增删快
ArrayList:查询快
适用场景:
LinkedList一般用于增删频繁的业务逻辑中,常会使用在池相关的技术中
ArrayList大多使用在查询频繁的业务中,一般“好友列表”,“商品列表”,“订单列表”都会使ArrayList
- LinkedList 类中的常用方法
- boolean add(Object element):向链表末尾添加一个新节点,该节点中的数据是参数element指定的对象
- void add(int index,Object element):向链表指定位置添加一个新节点,该节点中的数据是参数element指定的对象
- void addFirist(Object element):向链表表头添加一个新节点,该节点中的数据是参数element指定的对象
- void addLast(Object element):向链表表尾添加一个新节点,该节点中的数据是参数element指定的对象
- Object removeFirst():删除第一个节点并返回这个节点中的对象
- Object removeLast():删除最后一个节点并返回这个节点中的对象
- Object remove(int index):删除指定位置的节点
- Object get(int index):得到指定位置的节点
- Object getFirst():得到链表第一个节点的对象
- Object getLast():得到链表最后一个节点的对象
- int indexOf(Object element) :返回节点对象element在链表中首次出现的位置,如果链表中无此节点的对象则返回-1
- int lastIndexOf(Object element):返回节点对象element在链表中最后出现的位置,如果链表中无此节点的对象则返回-1
- Object set(int index,Object element):将当前链表index位置节点中的对象替换成参数element指定的对象,返回被替换对象
- int size():返回链表的长度即节点个数
- boolean contains(Object element):判断链表节点对象中是否含有element
ArraysList 和 LinkedList 的区别
- ArraysList数组列表是数组存储的整齐的规整的,查找方便,但是增删复杂,因为一旦添加数据,数组中的每一个元素都会有一定的移动。牵一发而动全身。
- LinkedList是链表存储,查询慢增删快,因为他们是散落的不好查,但是因为首位只有一个索引,随便找个地址存上数据就能把链表的索引一连就好了。
额外
为什么使用的时候都喜欢这样使用List<String> list = new ArrayList<>();
写成多态的形式。不是为了时尚或者习惯,或者书写定式。是为了让代码更具有扩展性,这样写对代码中的方法入口也很友好。但是想使用子类中独有的方法的时候一定要进行转型。当然没有必要的时候也可以不写成多态,写也可以。
Set
特点:无序(存和取的顺序不一致),不可重复
无序不可重复:这里的无序值的是存取方式不同,实际上内部元素排列是有规律的按照一定的算法排序的。所以存的时候不管怎么存,进去后自然是不变的顺序。Set是无序的没有下标的所以只能用迭代器来迭代。为了确保任何一种集合就要使用迭代。
Map
- Map接口中数据的存储方式与其他集合不同,它的数据是以键值对的形式进行存储的。
- 需要在创建Map集合时,明确Map中键(key)和值(value)的数据类型。
- 表示只有通过此键值对产生映射关系,才能确定一个确切的数据。
注:
- 键必须唯一
- 值可以重复
- Map是无序的
实现类:
HashMap
TreeMap
LinkedHashMap
- 常用方法:
- put(k,v):将k-v对存储到map中,并返回被覆盖的v
- remove(k):通过k删除整个k-v对,并返回被删除的v
- remove(k,v):只有键值对匹配时,才能删除,返回是否删除成功
- replace(k,v):将v替换指定k上的旧值,并返回被替换的值
- replace(k,oldValue,newValue):只有键和旧值匹配时,采用新值替换旧值,返回是否替换成功
- get(k):通过k返回对应的v
- isEmpty():判断map是否为空
- clear():清空map集合
- size():获取map集合长度
- containsKey(k):判断是否包含指定的键
- containsValue(v):判断是否包含指定的值
- put(k,v):将k-v对存储到map中,并返回被覆盖的v
- Map的迭代
- keySet()
- 集合中键组成的集合
- entrySet()
- 集合中键和值映射(对应)关系组成的集合。这里返回的是关系不是键也不是值。
- keySet()
Map的迭代
注:Map不能使用普通循环也不能使用增强for循环
原因是:Map不是数组,也不是Iterable的实例,Map不同于List、set,List、set都继承了Collection,而Collection继承了Iterable,所以List、Set就是Iterable的实例。因为Iterable里有iterator()方法。这个方法能够创建Iterator迭代器类对象,获取其迭代功能。所以List、Set不仅可以获取Iterator对象使用其功能,还能使用增强for循环。所以Map很孤独,它是它系列的顶级接口谁都依赖不上和谁都没有关系。而Iterator只是一个被利用的迭代器类,作用有两个,一是给Iterable的iterator()方法提供创建对象的可能。二是能在外部创建Iterator变量接受Iterable子类调用iterator()返回的Iterator对象,然后调用next();hasNext();等方法进行遍历。
keySet()
// 通过keySet方法获取map集合中所有键组成的集合
Set<String> set = map.keySet();
// 通过set的iterator方法获取set集合的迭代器对象
Iterator<String> it = set.iterator();
// 循环判断并获取
while(it.hasNext()){
<!--这里直接返回的就是key的值-->
String key = it.next();
<!--所以直接打印就是了-->
System.out.println(key +" = "+ key);
<!--这里可以通过get方法放入键来获取值-->
System.out.println(value +" = "+ map.get(key));
<!--要注意的是keySet的获取方法get和EntrySet的两个获取方法是不一样的,getKey\getValue-->
<!--get方法只有一个作用,放入键获取值-->
}
entrySet()
// 通过map的entrySet方法获取map中所有键值对的映射关系所组成的set集合
Set<Map.Entry<String, String>> set = map.entrySet();
// 通过set的iterator方法获取迭代器对象
Iterator<Map.Entry<String, String>> it = set.iterator();
// 循环判断并获取
while(it.hasNext()){
Map.Entry<String, String> en = it.next();
String key = en.getKey();
String value = en.getValue();
System.out.println(key +" - "+ value);
}
终于知道这个entrySet的返回类型是什么类型了,就是Map.Entry<>
类型,Map.Entry<String, String> en = it.next();
这一句就能看出是在把他里面的元素取出来。
迭代器
普通循环:
可以遍历数组、List增强for循环:
可以遍历数组、List、Set迭代器:
可以遍历List、Set、Map迭代器达到一种松耦合的效果,使用普通和增强的for循环要告诉别人它是什么类型的,存在于Set中还是List中的。它可以把你给他的任意类型转化成迭代器类型,它不管你是什么数据源,它可以包装一次,具有更好的复用性一致性。
迭代的步骤:
- 通过集合的iterator()方法获取迭代器对象,将迭代器与该集合绑定
- 循环,判断是否有可迭代的元素hasNext()
- 有,则使用next()获取
- 没有,则循环终止
注:
在迭代的过程中不能对集合进行增删改,会由于不确定性发生ConcurrentModificationException。
- 解决办法: 使用ListIterator
- 步骤:
- 通过list的litIterator()获取使用ListIterator对象
- 使用ListIterator的方法对集合进行改动
- ListIterator的方法:
- add(e)
- remove()
- set(e)
- nextIndex():获取下一个可迭代元素的下标
- previousIndex():获取上一个元素的下标
- previous():返回列表中的上一个元素,并向后移动光标位置。
Map没有继承Iterator所以里面没有iterator方法,但是Set是继承了的,可以使用。而Map中提供了keySet方法和entrySet方法。返回的是Set类型。这样就可以借助方法的返回值,与Set配置使用iterator方法进行遍历了。
额外
- Object里面有单独的工具类,Objects。Objects是兼容null的一个类库。
- Collection也有对应的Collections的工具类。
- 比如方法swap,交换指定列表中指定位置的元素。
- shuffle 打乱集合中的顺序。