集合就是一个可变长度的数组,集合的底层是数组。 集合分为两大类 : Collection集合 一个一个值
package com.xingyun.CollectionDemo; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class CollectionMethod { @SuppressWarnings("unlikely-arg-type") public static void main(String[] args) { Collection col = new ArrayList(); // 给集合添加整数类型 col.add(100); // 给集合添加字符串类型 col.add("hello"); col.add(123.45); // 返回集合中的元素个数 System.out.println("元素个数:" + col.size()); // 判断是否包含元素,不包含返回true System.out.println("col是否有元素:" + col.isEmpty()); // 从集合中移除某个元素 col.remove(123.45); for (Object object : col) { System.out.println("col:" + object); } System.out.println(); Collection col1 = new ArrayList(); // 判断是否包含元素,不包含返回true System.out.println("col1是否有元素:" + col1.isEmpty()); // 将集合col中的元素加入到col1中 col1.addAll(col); // 遍历col1中的值 for (Object object : col1) { System.out.println("col1:" + object); } System.out.println(); // 清除col1中的所有元素 col1.clear(); System.out.println("col1清除后:" + col1); // 查看集合中是否包含某个值 System.out.println("是否包含100:" + col.contains(100)); System.out.println("是否包含'hell':" + col.contains("hell")); System.out.println(); col.add("集合"); // 迭代集合 Iterator iterator = col.iterator(); int count = 0; // 判断有没有下一个元素 while (iterator.hasNext()) { if (count == 2) { System.out.println(col); boolean equals = col.equals("集合"); System.out.println(equals); } iterator.next(); count++; } // 将集合中的元素转换为数组 Object[] array = col.toArray(); for (Object object : array) { System.out.println("数组元素:" + object); } System.out.println(col); } }
List:有顺序 可以重复 List集合是一个有顺序(可以自己按照位置进行保存数据),元素的值可以重复,可以存null值。
ArrayList 列表集合 LinkedList 链表集合 Vector 线程安全的列表数组形式 Vector ArrayList
查找元素快:通过索引,可以快速访问指定位置的元素 增删元素慢: 指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置。如下图 指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新数组对应索引的位置,原数组中指定索引位置元素不复制到新数组中。如下图
列表集合 LinkedList 多个节点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素 增删元素快: 增加元素:操作如左图,只需要修改连接下个元素的地址即可。 删除元素:操作如右图,只需要修改连接下个元素的地址即可。
Iterator 与 ListIterator 的区别
ListIterator 只有list才有 可以对集合的元素进行添加、删除、修改的操作。 Iterator 只能进行删除操作。
Set 没有顺序 不可以重复 Set集合是中的元素不能重复,可以有null值但是只能有一个
HashSet 内部的数据结构是哈希表,是线程不安全的。 Treeset 可以对Set集合中的元素进行排序,是线程不安全的。HashSet,TreeSet部分方法
package com.xingyun.SetDemo; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; public class SetMethod { public static void main(String[] args) { //创建HashSet,TreeSet集合 Set hashset=new HashSet(); Set treeset=new TreeSet(); //给hashset添加值 hashset.add(500); hashset.add(100); hashset.add(700); hashset.add(400); //存储时,按照hash码顺序存储 System.out.println(hashset); System.out.println("集合为空?"+hashset.isEmpty()); //将hashset中集合元素存入到treeset中 treeset.addAll(hashset); //TreeSet内部将元素排序 System.out.println(treeset); int size = treeset.size(); System.out.println("treeset长度为:"+size); } }*
Hashset的底层是hashmap
Map 键值对集合 Map Hashmap:线程不安全按照hash码的值进行排序并允许使用null 值和null 键,hashmap 的执行速度要高于TreeMap TreeMap:键不能为null根据键的值使用自然排序的方式升序排序,可以使用 Comparator进行手动设置排序方式 hashTable:线程安全不允许使用null键值都不能为null
HashMap部分方法
package com.xingyun.MapDemo; import java.lang.reflect.Field; import java.util.HashMap; public class MapMethod { public static void main(String[] args) { HashMap<String, Integer> hashMap = new HashMap<>(); Class clazz = HashMap.class; // threshold是hashmap对象里的一个私有变量,若hashmap的size超过该数值,则扩容。这是通过反射获取该值 Field field; try { field = clazz.getDeclaredField("threshold"); // setAccessible设置为true可以开启对似有变量的访问 field.setAccessible(true); int threshold = 0; for (int i = 0; i < 1000; i++) { hashMap.put(String.valueOf(i), 0); if ((int) field.get(hashMap) != threshold) { threshold = (int) field.get(hashMap); // 默认的负载因子是0.75,也就是说实际容量是/0.75 System.out.println((int) field.get(hashMap) / 0.75); } } } catch (NoSuchFieldException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }1.一般情况下HashMap的速度大于LinkedHashMap,但是有一种情况除外,HashMap的容量很大,但是实际数据量很小,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。
HashMap 10000个数据 100有效数据 考虑所有 LinkedHashMap 10000个数据 100有效数据 只考虑有效数据
2.众所周知,集合具有扩容等特性,hashmap什么时候进行扩容呢? 当hashmap中的元素个数超过数组大小loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,也就是说,默认情况下,数组大小为16,那么当hashmap中元素个数超过160.75=12的时候,就把数组的大小扩展为216=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作。