嗯,实习的时候看到这个,感觉蛮好,这里摘录学习,生活加油:
我曾经害怕别人嘲笑的目光,后来,发现他们的目光不会在我身上停留太久,人们更愿意把目光放在自己身上。 知乎上看到,讲给自己。
List
List和Set都属于Collection的子接口,List集合中的元素是按照插入顺序进行排列的,允许出现重复元素,
List接口下的常用实现类有 ArrayList和LinkedList ,对于List来讲,
元素只能是通过set更新,不能通过add更新,通过add只能在指定索引位置添加元素,不会实现元素的覆盖,通过remove移除
ArrayList :
// 查找指定位置元素的下标 public int indexOf(Object o); // 查找指定元素最后一次出现的位置 public int lastIndexOf(Object o) ; // 清空集合元素 public void clear(); // 等等......
ArrayList的特点: **
ArrayList的迭代方式:
// 使用下标对List进行外部迭代
for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i));}
// 采用增强for的迭代方式其实底层是使用迭代器进行迭代,在迭代的过程中不允许对元素进行修改
for (String s : list) { System.out.println(s);}
// 内部迭代forEach,在迭代的过程中仍然不允许对元素进行修改过删除操作 list.forEach(item -> System.out.println(item)); // 内部迭代还支持并行方式对元素进行迭代 如果数据量非常大的时候可以采用该方式(一般不采用)迭代出来的元素可能无序 list.parallelStream().forEach(System.out::println);
list.stream().forEach(System.out::print);
public void forEach(Consumer<? super E> action) { Objects.requireNonNull(action);
final int expectedModCount = modCount; @SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData; final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) { action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
// 直接使用迭代器进行迭代 这种迭代方式允许在迭代中对元素进行修改和删除操作
Iterator<Long> iterator = list.iterator(); while (iterator.hasNext()){
System.out.println(iterator.next());
}
几种迭代方式的性能比较
在数据规模为 一千万的情况下内部迭代表现较好 ,尽管在千万级的数据量并 行迭代依然速度不快,因为在线程的频换 切换和销毁等因素造成了一定的开销。
在 百万数据规模 的情况下, 增强for的性能较好 ,可以根据数据量来对元素进行迭代, fori方式和增强for性能差异不是很大。
LinkedList:
LinkedList继承自AbstractSequentialList可以知道LinkedList的元素是 顺序访问的 ,随机访问元素需要对链表进行遍历, 同样实现了克隆和序列化接口LinkedList还实现了 Deque相关的方法 ,可以当做一个队列来使用
LinkedList的类继承关系
LinkedList的特点:
LinkedList的迭代方式
所以我们在使用LinkedList的时候不采用fori形式的遍历
几种迭代方式的比较:
ArrayList和LinkedList的区别
Map 是 双列集合,即存储元素的时候是键值对的形式在Map中存储的,一个Entry<K,V>结构的键值对映射,一个键对 应一个值,不允许出现重复的键,
HashMap
HashMap的类继承关系:
HashMap的特点
HashMap的迭代方式
// 获取到所有的key然后依次进行获取
Set<Integer> keySet = map.keySet(); Integer val = 0;
for (Integer key : keySet) { val = map.get(key);
System.out.print("");
}
Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
for (Map.Entry<Integer, Integer> entry : entrySet) {
System.out.print("");
}
Map<Object,Object> objectObjectMap = new HashMap<>();
objectObjectMap.forEach( (o1, o2) ->System.out.println(o1.toString()+o2));
// 内部迭代底层依然是使用entrySet进行迭代,效率不如直接使用外部迭代
default void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) { K k;
V v; try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map. throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
LinkedHashMap:
HashMap的类继承关系
LinkedHashMap的数据结构
LinkedHashMap的特点
LinkedHashMap的迭代方式
public void forEach(BiConsumer<? super K, ? super V> action) { if (action == null)
throw new NullPointerException(); int mc = modCount;
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) action.accept(e.key, e.value);
if (modCount != mc)
throw new ConcurrentModificationException();
}
TreeMap
TreeMap中的元素默认按照keys的自然排序排列。(对Integer来说,其自然排序就是数字的升序;对String来说,其自然排序就是按照字母表排序)
TreeMap的定义如下:
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable
TreeMap继承AbstractMap,实现NavigableMap、Cloneable、Serializable三个接口。其中AbstractMap表明TreeMap为一个Map即支持key-value的集合, NavigableMap(更多)则意味着它支持一系列的导航方法,具备针对给定搜索目标返回最接近匹配项的导航方法 。
TreeMap中同时也包含了如下几个重要的属性:
//比较器,因为TreeMap是有序的,通过comparator接口我们可以对TreeMap的内部排序进行精密的控制 private final Comparator<? super K> comparator; //TreeMap红-黑节点,为TreeMap的内部类 private transient Entry<K,V> root = null; //容器大小 private transient int size = 0; //TreeMap修改次数 private transient int modCount = 0; //红黑树的节点颜色--红色 private static final boolean RED = false; //红黑树的节点颜色--黑色 private static final boolean BLACK = true;
对于叶子节点Entry是TreeMap的内部类,它有几个重要的属性:
//键 K key; //值 V value; //左孩子 Entry<K,V> left = null; //右孩子 Entry<K,V> right = null; //父亲 Entry<K,V> parent; //颜色 boolean color = BLACK;
数据结构:基于红黑树的一种实现,红黑树是自平横的二叉搜索树。二叉搜索树是排序好的二叉树。
Set
Set集合存储元素的特点就是, set存储元素都是无序并且不可重复的,比较常用的两种有HashSet和TreeSet
HashSet:
Hashset的顶级接口是 Collection接口,属于单列集合,即每次存储一个元素
HashSet的数据结构
private transient HashMap<E,Object> map;// 内部维护了一个map,其底层实现靠的就是HashMap,键用于存放值
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();// 这个空的Object对象作为所有的默认Value
/**
*Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
*default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
// add方法其实就是调用了map的put,并传入一个空的value
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
因为Set的元素和HashMap中的键是有相同的特征的,HashSet充分利用了HashMap的功能
HashSet的特点:
public Iterator<E> iterator() { return map.keySet().iterator();
}
set.forEach(k->System.out.println(k));
TreeSet
TreeSet的特点
public TreeSet() {
this(new TreeMap<E,Object>());
}