【Java】 - 集合
- 一、基本概念及相关知识
- 1.1集合概述
- 1.2 迭代器
- 二、集合接口
- 2.1 Collection
- 2.1.1 List
- 2.1.2 Queue
- 2.1.3 Set
- 2.2 Map
- 三、实现接口的类
- 3.1 ArrayList
- 3.2 LinkedList
- 3.3 HashSet
- 3.4 hashMap
- 一、参考资料
一、基本概念及相关知识
1.1集合概述
Java集合类存放在java.util包中,是一个可以动态存储任意数量具有相同属性的对象的容器。
注意:
①集合只能存放对象。若将一个基础数据类型的数据放入集合中,它会自动转换成其包装类(装箱)后再存入,如int 类型值为20的数据,会装成值为20的Integer对象存入。
②集合存放的都是对象的引用,而非对象本身,对象本身还是放在堆内存中。
③集合可以存放不同类型,不限数量的数据类型。
应用场景:
①存储数据的数量不确定的情况
②同时存储具有一对一关系的数据
③需要对数据进行增删
④要考虑数据重复的情况。
集合框架分为两类,Collection与Map,Collection主要存储类的对象,Map则是以键值对的形式存放数据。
1.2 迭代器
Collection的父接口是Iterable,Iterable中仅含一个Iterator iterator()方法,该方法返回类型为T的一组元素的迭代器(即将该集合元素存在迭代器中返回)。所以通常定义一个Iterator对象?,并将实现Collection或其子接口的类的对象调用iterator()方法得到的迭代器赋值给它。
Iterator< E >接口可以以统一的方式实现对集合元素的遍历。
接口方法:
boolean hasNext()
E next()
void remove() //从基础集合中删除此迭代器返回的最后一个元素。
注意:
重新遍历时需要将迭代器再次赋值。因为若不更新迭代器,迭代器还指向上次遍历的最后一个元素的位置。
二、集合接口
2.1 Collection
boolean add(E e)
boolean addAll(Collection<? extends E> c)
void clear()从此集合中删除所有元素(可选操作)。
boolean remove(Object o)
boolean removeAll(Collection<?> c)
default boolean removeIf(Predicate<? super E> filter)删除满足给定谓词的此集合的所有元素。
boolean retainAll(Collection<?> c)仅保留此集合中包含在指定集合中的元素(可选操作)。
boolean contains(Object o)
boolean containsAll(Collection<?> c)
boolean equals(Object o)将指定的对象与此集合进行比较以获得相等性。
int hashCode()返回此集合的哈希码值。
boolean isEmpty()
Iterator iterator()返回此集合中的元素的迭代器。
default Stream parallelStream()返回可能并行的 Stream与此集合作为其来源。
int size()
default Spliterator spliterator()创建一个Spliterator在这个集合中的元素。
default Stream stream()返回以此集合作为源的顺序 Stream 。
Object[] toArray()返回一个包含此集合中所有元素的数组。
T[] toArray(T[] a)返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
2.1.1 List
List元素有序、不可重复。
void add(int index, E element)将指定的元素插入此列表中的指定位置(可选操作)。
addAll(int index, Collection<? extends E> c)
E get(int index)返回此列表中指定位置的元素。
int indexOf(Object o)返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
int lastIndexOf(Object o)
ListIterator listIterator()返回列表中的列表迭代器(按适当的顺序)。
ListIterator listIterator(int index)从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。
E remove(int index)
E set(int index, E element) 修改元素
default void replaceAll(UnaryOperator operator)将该列表的每个元素替换为将该运算符应用于该元素的结果。
default void sort(Comparator<? super E> c)给列表排序
List subList(int fromIndex, int toIndex)返回此列表中指定的 fromIndex (含)和 toIndex之间的视图。
2.1.2 Queue
boolean add(E e)
boolean offer(E e)如果在不违反容量限制的情况下立即执行,则将指定的元素插入到此队列中。
E element()检索,与peek()的区别是如果此队列为空,它将抛出异常
E peek()检索但不删除此队列的头,如果此队列为空,则返回 null
E poll()检索并删除此队列的头,如果此队列为空,则返回 null 。
E remove()检索并删除此队列的头,为空则抛出异常。
2.1.3 Set
set中的元素无序,不允许重复。
2.2 Map
Map中的数据是以键值对(Key-Value)的形式存储的,且Key与Value通过映射一 一对应,通过Key可以快速查找到Value。在一个映射中Key是唯一的,Value可以不唯一。Key-Value是以Entry类型的对象实例存在。
接口方法
void clear()删除所有
V get(Object key)返回到指定键所映射的值,或 null如果此映射包含该键的映射。
Set<Map.Entry<K,V>> entrySet()返回该字典中所有键值对的信息。
Set keySet()返回该字典中所有键的信息。
Collection values()返回该字典中所有value的信息。
default V getOrDefault(Object key, V defaultValue)
V put(K key, V value)
void putAll(Map<? extends K,? extends V> m)
default V putIfAbsent(K key, V value)如果指定的键尚未与某个值相关联(或映射到 null )将其与给定值相关联并返回 null ,否则返回当前值。
V remove(Object key)
default boolean remove(Object key, Object value)
default V replace(K key, V value)
default boolean replace(K key, V oldValue, V newValue)
default void replaceAll(BiFunction<? super K,? super V,? extends V> function)将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。
default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)尝试计算指定键的映射及其当前映射的值(如果没有当前映射, null )。
default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)如果指定的键尚未与值相关联(或映射到 null ),则尝试使用给定的映射函数计算其值,并将其输入到此映射中,除非 null 。default V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)如果指定的密钥的值存在且非空,则尝试计算给定密钥及其当前映射值的新映射。
boolean containsKey(Object key)如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value)如果此地图将一个或多个键映射到指定的值,则返回 true 。
boolean equals(Object o)
default void forEach(BiConsumer<? super K,? super V> action)
int hashCode()返回此地图的哈希码值。
boolean isEmpty()如果此地图不包含键值映射,则返回 true 。
default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)如果指定的键尚未与值相关联或与null相关联,则将其与给定的非空值相关联。
int size()返回此地图中键值映射的数量。
三、实现接口的类
3.1 ArrayList
实现了List接口
应用: ArrayList
底层实现: ArrayList底层是数组实现的。故而只在尾部增删数据比较方便。适合查找和更新元素。元素可以为null。
构造方法
ArrayList()构造一个初始容量为10的空列表。
ArrayList(Collection<? extends E> c)构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。
ArrayList(int initialCapacity)构造具有指定初始容量的空列表。
新增方法
Object clone()返回此 ArrayList实例的浅拷贝。
void ensureCapacity(int minCapacity)如果需要,增加此 ArrayList实例的容量,以确保它可以至少保存最小容量参数指定的元素数。
void forEach(Consumer<? super E> action)对 Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。
protected void removeRange(int fromIndex, int toIndex)从这个列表中删除所有索引在 fromIndex (含)和 toIndex之间的元素。
subList(int fromIndex, int toIndex)返回此列表中指定的 fromIndex (包括)和 toIndex之间的独占视图。
void trimToSize()修改这个 ArrayList实例的容量是列表的当前大小。
3.2 LinkedList
实现了List接口和Queue接口
构造方法
LinkedList()构造一个空列表。
LinkedList(Collection<? extends E> c)构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。
新增方法
void addFirst(E e)在该列表开头插入指定的元素。
void addLast(E e)将指定的元素追加到此列表的末尾。
Object clone()返回此 LinkedList的浅版本。
Iterator descendingIterator()以相反的顺序返回此deque中的元素的迭代器。
E getFirst()返回此列表中的第一个元素。
E getLast()返回此列表中的最后一个元素。
boolean offerFirst(E e)在此列表的前面插入指定的元素。
boolean offerLast(E e)在该列表的末尾插入指定的元素。
E peekFirst()
E peekLast()
E pollFirst()
E pollLast()
E pop()
void push(E e)
E removeFirst()
E removeLast()
boolean removeFirstOccurrence(Object o)删除此列表中指定元素的第一个出现(从头到尾遍历列表时)
boolean removeLastOccurrence(Object o)删除此列表中指定元素的最后一次出现(从头到尾遍历列表时)。
E set(int index, E element)用指定的元素替换此列表中指定位置的元素。
3.3 HashSet
实现了Set接口
应用: HashSet可以方便高效地实现去重、集合运算等功能。有良好的的存取和查找性能。
底层实现: HashSet底层是hashMap。
构造方法
HashSet()构造一个新的空集合; HashMap实例具有默认初始容量(16)和负载因子(0.75)。
HashSet(Collection<? extends E> c)构造一个包含指定集合中的元素的新集合。
HashSet(int initialCapacity)构造一个新的空集合; HashMap实例初始容量(initialCapacity)和默认负载因子(0.75)。
HashSet(int initialCapacity, float loadFactor)构造一个新的空集合; 指定实例的初始容量和指定的负载因子。
新增方法
Object clone()返回此 HashSet实例的浅层副本:元素本身不被克隆。
重要方法
boolean equals(Object o)将指定的对象与此集合进行比较以获得相等性。
int hashCode()返回此集合的哈希码值。
为达到HashSet不重复的要求,在元素放入时,先判断集合中有无元素的hashCode与待放入元素的相同,若无,说明这是一个新元素,存储;若有,且equles判断相等,说明元素已经存在,不存;若有,且equles判断不相等,说明元素不存在,存。这个过程需要调用hashCode()和equals()方法。
hashCode()根据一定规则将数据分类存放;equals()根据比较元素具体内容判断两个元素内容是否相同。故而根据hashCode()和equals()可以唯一标识元素。当自定义元素类时,可以根据需求重写hashCode()和equals()方法,如果没有重写这两个方法,这两个方法默认根据自定义类对象的所有属性值进行运算。
对于HashSet集合内的对象来说,无法通过集合对象名修改集合中的对象,若通过对象本身的名字修改它,则它的hashCode值将改变。
例:
删除单个元素(集合遍历过程中不允许删除元素,故remove一个元素后必须马上停止遍历。)
for(Notice no:noticelist){
if(no.getName().equals("zyl"))
{noticelist.remove(no);break;}
}
删除多个元素
Set< Notice > delete=new HashSet<>();
for(Notice no:noticelist){
if(no.getName().equals("zyl"))
delete.add(no);
}
noticelist.removeAll(delete);
3.4 hashMap
实现了Map接口
允许使用null值,Entry对象是无序的。
构造方法
HashMap()构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
HashMap(int initialCapacity)构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
HashMap(int initialCapacity, float loadFactor)构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap(Map<? extends K,? extends V> m)构造一个新的 HashMap与指定的相同的映射 Map 。
新增方法
Object clone()返回此 HashMap实例的浅拷贝:键和值本身不被克隆。
例
1.输入key-value值:利用HashMap对象.put(key, value);
int num=0;
while(num<3){
Goods good=new Goods();
System.out.println("请输入第"+(num+1)+"商品编号:");
good.setId(scan.next());
System.out.println("请输入第"+(num+1)+"商品名称:");
good.setName(scan.next());
try{
System.out.println("请输入第"+(num+1)+"商品价格:");
good.setPrice(scan.nextDouble());
}catch(java.util.InputMismatchException e){
scan.next();
System.out.println("请输入符合规范的数据");
continue;
}
goods.put(good.getId(), good);
num++;
}
// Goods good=new Goods("10008","火锅",200);
// goods.put("10008",good);
// good=new Goods("10007","秋葵",20);
// goods.put("10007",good);
// good=new Goods("10006","白菜",10);
// goods.put("10006",good);
2.遍历key或value值:
法一:迭代器方法。利用“HashMap对象.keySet().iterator()”或“HashMap对象.values().iterator()”。因为keySet()返回的是一个Set集合,values()返回的是Collection集合,实现了Collection接口的类对象可以调用Iterator()方法返回一个包含该集合元素的迭代器。
Iterator<Goods> it=goods.values().iterator();//Goods是自定义商品类,goods是一个HashMap类对象。
while(it.hasNext()){
System.out.println(it.next());//在Goods类重写ToString()方法,这样输出才是value具体信息;否则输出的是value的引用。
}
法二:增强for循环方法。见3
3.迭代遍历Key-Value值:
增强for循环遍历。可以用hashMap对象调用entrySet()方法得到key-value的Set集合。
Set<java.util.Map.Entry<String, String>> answer=words.entrySet();
for(java.util.Map.Entry<String, String> a:answer){
System.out.println(a.getKey()+":"+a.getValue());
}
也可以用keySet()得到key值,然后通过key值得到value输出。
Set<String> id=goods.keySet();
for(String s:id){
System.out.println("key:"+s+" value"+goods.get(s).toString());
}
(查询key-value 用迭代器遍历也能做,就是更麻烦,要声明变量暂存key,再用get方法得到value,那不如直接用增强for)
4.查询某key对应的value
Scanner scan=new Scanner(System.in);
boolean flag=false;
String key=scan.next();
Set<String> keys=words.keySet();
for(String s:keys){
if(s.equals(key))
{
System.out.println("key:"+key+",value:"+words.get(key));
flag=true;
break;
}
}
if(flag==false){
System.out.println("未找到!");
}