一、HashMap类
1、底层存储方式:
1.1 HashMap在JDK1.7之前底层是用数组+链表的方式存储的;在JDK1.8之后底层是用数组+链表+红黑树存储的。
1.2 HashMap里面实现了一个静态内部类Entry。
1.3 Entry的属性有key,value,next,hash。Entry存储的是key-value键值对。
1.4 HashMap存储是无序的。
1.5 HashMap可以存储null值。
2、遍历方式有4种:
public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "test1"); map.put("2", "test2"); map.put("3", "test3"); //第一种方式:使用使用较多 通过Map.keySet遍历key和value for (String key : map.keySet()) { System.out.println("获取Map中key的值 "+ key); System.out.println("根据key获取value的值 " + map.get(key)); } //第二种 "通过Map.entrySet使用iterator遍历key和value:" Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("获取Map中key的值 " + entry.getKey()); System.out.println("获取value的值 " + entry.getValue()); } //第三种:使用比较多,推荐使用,尤其是容量大时 for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("获取Map中key的值" + entry.getKey()); System.out.println("获取value的值" + entry.getValue()); } //第四种:使用很少,不推荐 "通过Map.values()遍历所有的value,但不能遍历key" for (String v : map.values()) { System.out.println("value= " + v); } }
二、ArrayList类
1、概述:
1.1 ArrayList是基于数组实现的,是动态数组,容量能自动增长。
1.2 ArrayList线程不安全,只能在单线程下使用。多线程环境下使用Collections.synchronizedList(List)返回一个线程安全的ArryayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。
1.3 ArrayList实现了Serializable接口,因此支持序列化传输;ArrayList实现了RandomAccess接口,因此支持通过下标序号进行快速访问;ArrayList实现了Cloneable接口,因此支持被克隆。
1.4 通过ensureCapacity增加ArrayList类的容量。
1.5 无参构造方法构造的容量默认为10,带有Collection参数的构造方法,将collection转化为数组赋给ArrayList的实现数组elementData
1.6 ArrayList实现中调用了Arrays.copyof()方法,该方法就是在内部创建一个长度为newlength的数组;调用System.arraycopy方法,该方法被标记了native,可以保证数组内元素的正确复制和移动,适合批量处理数组,效率较高。
1.7 ArrayList基于数组实现,通过下标索引查找指定位置的元素,因此查询效率高;插入和删除效率低。
1.8 ArrayList将元素的值分为null和不为null两种情况处理,支持null存储。
1.9 ArrayList是有序的,可以包含重复数据。
2、遍历方式分为5种:
public class Test { public static void main(String[] args) { List<Integer> list=new ArrayList<Integer>(); int n=100; while (n>0){ list.add(n); n--; } //1.效率最高,也是官方推荐用法 for (int i = 0; i < list.size(); i++) { System.out.print(i); } //2.底层通过Iterator操作底层数组,其中remove()方法迭代过程中删除元素的唯一方法。 for (Iterator it=list.iterator();it.hasNext()){ System.out.print(it.next()); } //3.增强for循环底层用Iterator实现的,相当于增强for循环是在第二种方法外包了一层,效率稍微低 for (int i:list){ System.out.print(i); } //4.底层源码是通过增强for实现的,相当于在 增强for外又包了一层,效率较低(JDK5特性) list.forEach(item -> {}); //5.支持多线程操作 list.stream().forEach(item -> {}); } }
三、Set类
1、概述
1.1 hashSet底层是基于hashMap存储的。
1.2 hashSet存储的元素是无序的,更不能保证顺序恒久不变。
1.3 hashSet不是不同步的,需要外部保持线程之间的同步问题。
1.4 hashSet允许存储null值。
1.5 hashSet不能存储重复值。
1.6 hashSet存储值,必须覆盖hashCode()方法和equals()方法。
2、遍历方式有2中:
public class Test{ public static void main(String[] args) { Set<String> set=new HashSet<String>(); for (int i = 0; i <5 ; i++) { set.add(""+i); } //1.迭代遍历(针对字符串) Iterator<String> it=set.iterator(); while (it.hasNext()){ String str=it.next(); System.out.print(str); } //或者 for (Iterator it2=set.iterator();it2.hasNext();){ System.out.print(it2.next()); } //2.for遍历(针对字符串) for (String s:set){ System.out.print(s); } //3.遍历对象并不能重复 //定义实体类 public class User{ private String name; private String age; //get和set方法 public String getName() {return name;} public void setName(String name) {this.name = name;} public String getAge() {return age;} public void setAge(String age) { this.age = age; } //重写toString方法 @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age='" + age + '\'' + '}'; } //重写equals方法,判断的准则是 name和age @Override public boolean equals(Object o) { //如果值相等就返回 if (this == o) return true; //快速排除非User类和null if (!(o instanceof User)) return false; //强制转换 User user = (User) o; if (name != null ? !name.equals(user.name) : user.name != null) return false; return age != null ? age.equals(user.age) : user.age == null; } //重写hashCode方法 @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (age != null ? age.hashCode() : 0); return result; } }
//遍历存储的对象并保证不重复 Set<User> set2=new HashSet<User>(); set2.add(new User("张三","20")); set2.add(new User("李四","30")); for (Iterator<User> it3=set2.iterator();it3.hasNext();){ System.out.print(it3.next()); } } }