Collection 接口
:
Collection 接口
public boolean add(E e)
:把给定的对象添加到集合中去。public void clear()
:清空集合中所有元素。public boolean remove(E e)
:把给定对象在当前集合中删除。public boolean contains(Object obj)
:判断当前集合中是否包含给定对象。public boolean isEmpty()
:判断当前集合是否为空。public int size()
:返回当前集合中元素的个数。迭代器遍历
:迭代器在Java中的类是Irerator
,迭代器是集合专用的遍历方式。
Collection集合获取迭代器:
Iterator<E> iterator()
返回迭代器对象,默认指向当前集合的0索引。Iterator常用方法:
boolean hasNext()
:判断当前位置是否有元素,有返回true,无返回false。E next
:获取当前位置元素,并将迭代器对象移动到下一个位置。//迭代器遍历示例:
List<String> list = new ArrayList<>();
//list.add()...装入数据
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){ //当前位置有无元素?
String str = iterator.next(); //获取当前位置元素,指向下一位置
System.out.println(str); //打印
//iterator.remove(); 删除
}
Coding细节:
增强for循环遍历
:增强for循环的底层就是迭代器,简化了迭代器的代码书写。
出现在JDK5之后,内部原理就是一个Iterator迭代器。
所有的单列集合和数组可以用增强for循环进行遍历。
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add(".29.");
coll.add("ebb29bbe");
//增强for
for(String str : coll){
System.out.println(str);
}
利用lambda表达式遍历
:Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add(".29.");
coll.add("ebb29bbe");
//遍历
coll.forEach( str -> System.out.println(str) );
List接口
:
void add(int index,E element)
:在集合指定位置插入元素。E remove(int index)
:删除指定索引位置的元素,返回被删除的元素。E set(int index,E element)
:修改指定索引位置的元素,返回被修改的元素。E get(int index)
:返回指定索引位置的元素。迭代器
:参照Collection集合
增强for循环
:参照Collection集合
Lambda表达式
:参照Collection集合
列表迭代器
:
List<String> list = new ArrayList<>();
list.add("ebb29bbe");
ListIterator<String> iterator = list.listIterator();
while(iterator.hasNext()){
String str = iterator.next();
//可在遍历过程新增元素
iterator.add(".29.");
}
//遍历到末尾,可使用方法从后往前遍历
while(iterator.hasPrevious()){
String str = iterator.previous();
//可在遍历过程新增元素
iterator.add(".29.");
}
for循环
:List<String> list = new ArrayList<>();
list.add("ebb29bbe");
for(int i = 0;i < list.size(); ++i){
String str = list.get(i);
System.out.println(str);
}
ArrayList底层原理
:
LinkedList使用
:
public void addFirst(E e)
:在列表开头插入指定元素public void addLast(E e)
:将指定元素追加到列表末尾public E getFirst()
:返回列表中的第一个元素public E getLast()
:返回列表中的最后一个元素public E removeFirst()
:从列表中删除并返回第一个元素public E removeLast()
:从列表中删除并返回最后一个元素Iterator底层原理
:
Iterator
实例,底层就是创建了一个Iterator内部类的对象,这个内部类就代表迭代器。hasNext()
底层就是用当前索引与集合长度作比较,索引不等于长度就返回true,否则返回false。next()
底层最开始会验证当前集合操作次数与开始记录的操作次数是否一致,不一致说明迭代器使用期间使用了集合的方法进行新增/删除,进而抛出并发修改异常(ConcurrentModificationExcelption)。hashCode()
,不同对象计算出的哈希值是不同的。hashCode()
,不同的对象属性值相同时,计算出的哈希值相同。HashSet
底层原理:
集合方法基本与Collection集合方法一致
JDK8之前
:数组 + 链表JDK8开始
:数组 + 链表 + 红黑树
int index = (数组长度 - 1) & 哈希值;
null
,如果是就直接存入。null
,通过equals() 比较属性值,属性值一致不会存入数据,属性值不一致时,存入索引位置,形成链表。JDK8之前
:新元素存入数组,老元素挂在新元素下面。JDK8开始
:新元素直接挂在老元素下面。(当链表长度大于8而且数组长度大于等于64时,当前链表会自动转换成红黑树存储数据) 注意:如果集合中要存储的是自定义对象时,一定要重写equals() 和 hashCode()。
问题一:HashSet为什么存取顺序不一致
:底层数组存储的是链表,而遍历这些链表时,与存储数据时的顺序很可能不一致。
问题二:HashSet为什么没有索引
:底层时数组+链表+红黑树,很难去规定索引。
问题三:HashSet是利用什么机制保证数据去重的?
利用hashCode方法和equals方法保证去重,因为方法重写后,属性值一致的对象哈希值一致,存放的位置一致,若equals比较到相同,会不做存入操作。
LinkedHashSet底层原理
:
集合方法基本与Collection集合方法一致
TreeSet
:
集合方法基本与Collection集合方法一致
双列集合特点
:
Map集合
:
V put(K key,V value)
:添加元素V remove(Object key)
:根据键删除键值对void clear()
:移除所有的键值对boolean containsKey(Object key)
:判断集合中是否包含指定键boolean cintainsValue(Object value)
:判断集合中是否包含指定值boolean isEmpty()
:判断集合是否为空int size()
:集合的长度,也就是集合中键值对的个数通过键找值方式-增强for
://实例化Map集合
Map<String,String> map = new HashMap<>();
//添加元素:
map.put("1","29");
map.put("2","002900");
map.put("3","..29..");
//根据键找值
Set<String> keys = map.keySet();//所有键的set集合
for(String key : keys){ //遍历所有的键
String value = map.get(key); //根据键找值
System.out.println(key + "--" + value); //打印
}
通过键找值的方式,还可以通过迭代器Iterator、Lambda表达式等方式来实现,可参照上文的Collection遍历方式,这里不做补充。
键值对方式 - 增强for
://实例化Map集合
Map<String,String> map = new HashMap<>();
//添加元素:
map.put("1","29");
map.put("2","002900");
map.put("3","..29..");
//键值对方式
Set<Map.Entry<String,String>> entrys = map.entrySet();
for(Map.Entry<String,String> entry : entrys){
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "--" + value); //打印
}
Lambda表达式
://实例化Map集合
Map<String,String> map = new HashMap<>();
//添加元素:
map.put("1","29");
map.put("2","002900");
map.put("3","..29..");
//Lambda表达式
map.forEach((key,value)-> System.out.println(key + "--" + value));
HashMap底层原理
:
hashCode()
,不同对象计算出的哈希值是不同的。hashCode()
,不同的对象属性值相同时,计算出的哈希值相同。底层原理
:
int index = (数组长度 - 1) & 哈希值;
null
,如果是就直接存入。null
,通过equals()比较键的值,值一致会进行覆盖(键值对的旧value值被新value值覆盖),属性值不一致时,存入索引位置,形成链表。JDK8之前
:新元素存入数组,老元素挂在新元素下面。JDK8开始
:新元素直接挂在老元素下面。(当链表长度大于8而且数组长度大于等于64时,当前链表会自动转换成红黑树存储数据)LinkedHashMap特点
:
TreeMap
:
Collections
:
public static <T> boolean addAll(Collections<T> c,T... elements)
:向指定单列集合中批量添加元素。public static void shuffle(List<?> list)
:打乱List集合中元素的顺序。public static <T> void sort(List<T> list)
:排序。public static <T> void sort(List<T> list,Comparator<T> c)
:按照指定规则排序。public static <T> int binarySearch(List<T> list,T key)
:通过二分查找法查找元素。public static <T> void copy(List<T> dest,List<T> src)
:拷贝集合中的元素。public static<T> int fill(List<T> list,T obj)
:使用指定元素填充集合。public static <T> void max(Collection<T> c)
:获取默认自然排序后的元素最大值。public static <T> void min(Collection<T> c)
:获取默认自然排序后的元素最小值。public static <T> void swap(List<?> list,int i,int j)
:交换集合中指定索引位置的元素。应用场景
:
使用
:
static <E> List<E> of(E...elements)
:创建一个具有指定元素的List集合对象。static <E> Set<E> of(E...elements)
:创建一个具有指定元素的Set集合对象。static <K,V> Map<K,V> of(E...elements)
:创建一个具有指定元素的Map集合对象。(传递参数存在上限 - 20个参数,即10个键值对,超过10个需要用ofEntries方法)注意 —— 上述方式创建的集合的元素不能添加、不能修改、不能删