标签:二分插入排序 gen 通配 equals 问题 city 二进制 也会 quic
Iterator
,Collection
,Map
Collections
Arrays
1.Arrays.sort()
2.Collections.sort()
(底层是调用 Arrays.sort())
1.对于原始数据类型,目前使用的是所谓双轴快速排序(Dual-Pivot QuickSort),是一种改
进的快速排序算法,早期版本是相对传统的快速排序DualPivotQuicksort.java
typically faster than traditional (one-pivot) Quicksort implementations
2.对象数据类型 使用TimSort 归并和二分插入排序(binarySort)结合的优化排序算法
思路:
查找数据集中已经排好序的分区(这里叫 run),
然后合并这些分区来达到排序的目的。
{1, 2, 3, 4, 5, 9, 7, 8, 10, 6}
输出 6{9,8,7,6,5,4, 10}
输出6 并且reverse(0,6)
->[4, 5, 7, 6, 8, 9, 10]
1 | private static <T> int (T[] a, int lo, int hi, |
3.java8的parallelSort
ForkJoin框架
Java 9 中,Java 标准类库提供了一系列的静态工厂方法,比如,List.of()、Set.of(),大大简
化了构建小的容器实例的代码量。不可变的,符合我们对线程安全的需求
同:
1.都实现集合框架中的 List,有序集合。
2.都可以按照位置进行定位、添加或者删除的操作,都提供迭代器以遍历其内容。
不同:
1.Vector在扩容时会提高 1 倍,而 ArrayList 则是增加 50%。
vector:
1 | int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity); |
2.只有Vector是线程安全的。
fianl修饰的变量,JVM也会提前给我们初始化好。???
1 | //变量 |
.add(e)
minCapacity = Math.max(DEFAULT_CAPACITY=10, minCapacity
int newCapacity = oldCapacity + (oldCapacity >> 1);
//>>=/2.remove(index)
1.将index+1后的numMoved个元素从index开始复制obj->obj
1 | System.arraycopy(elementData, index+1, elementData, index, |
2.长度-1,最后一个null elementData[--size] = null;
.romove(Object o)
循环查找o==null!=null->fastremove(index)(基本同上)1 | //当o!=null,按List规范重写equal!! |
@SuppressWarnings("unchecked")
编译器消除警告1.ArrayListhe和Vector在用法上完全相同addElement(Object obj)
和add(Object obj)
没什么区别
1 | public synchronized void addElement(E obj) { |
1 | public synchronized boolean add(E e) { |
Vector里有一些功能重复的方法,这些方法中方法名更短的是属于后来新增的方法.更长的是原先vector的方法.而后来ArrayList是作为List的主要实现类.
线程同步不应该使用Vector 应该使用java.util.concurrent.CopyOnWriteArrayList
class Stack<E> extends Vector<E>
Deque 接口及其实现提供了 LIFO 堆栈操作的更完整和更一致的 set
Deque<Integer> stack = new ArrayDeque<Integer>();
LinkedList<E> implements List<E>, Deque<E>,
https://github.com/CarpenterLee/JCFInternals/blob/master/markdown/4-Stack%20and%20Queue.md
head
指向首端第一个有效元素,tail
指向尾端第一个可以插入元素的空位
1 | elements[head = (head - 1) & (elements.length - 1)] = e;//越界处理 |
1.head前有空位 2.head是0,加到最后,如果最后是tail则扩容:
1 | int head = 10; |
1 | elements[tail] = e; |
System.arraycopy
1 | native void arraycopy(Object src, //原数组 |
1 | int p = head; |
1 | public E pollFirst() { |
int t =(tail-1)&(element.length-1);
Queue queue = new LinkedList();
内部静态类Node
String可以
1 | String[] ss = {"da","da"}; |
基本数据类型不行
1 | int[] ss = {1,2}; |
源码:基本数据类型
1 | public static <T> List<T> asList(T... a) { |
类型参数放在修饰符public static后,返回类型之前
<T extends AutoCloseable> void closeAll(ArrayList<T> elems)
确保Array的元素类型是AutoCloseable的子类;extends
表示子类型、类型限定T extends Runnable & AutoCloseable
,只能有一个限定类,放在第一个,其它都是接口ArrayList<Manger>
不是ArrayList<Employee>
子类1 | ArrayList<Manger> bosses = new ArrayList<>(); |
如果使用数组Manger[]和Employee[] 转型是合法的,但赋值会爆ArrayStoreException
如果不对ArrayList写操作,转换是安全的。可以用子类通配符
<? extends Employee> staff
可以传Arraylist<? extends Employee>
转成Employee
<? extends Employee>
<? super Employee>
常用于函数式对象参数(用lambda调用)1 | List<String> l1 = new ArrayList<String>(); |
1 | List<Integer> l2 = new ArrayList<Integer>(); |
类型变量不能实例化 T[] result = new T[n];
错误
Sting[]::new
IntFunction<T[]> constr
T[] result = constr.apply(n)
反射
1 | public static <T> T[] repeat(int n,T obj,Class<T> c1){ |
调用String[] greetings = repeat(10,"Hi",String.class);
1 | public static <T> ArrayList<T> repeat(int n,T obj){ |
泛型数组Entry<String,Integer>[]
是合法的,但是初始化要@SuppressWarnings(“unchecked”)
正确方法:ArrayList<Entry<String,Integer>>
1 | //可以 |
ImmutableList<String> ilist = ImmutableList.of("a","b");
不可变ListLists
1 | List<String> lit = Lists.newArrayList("aaa","ddd","bbb"); |
1 | Collection<String> cl =Collections2.filter(lit,(e)->e.toUpperCase().startsWith("a")); |
转换 (有问题)日期
1 | Set<Long> set = Sets.newHashSet(20170801L,20980320L,19950730L); |
组合函数Functions.compose(f1,f2)
用google的Function
SetView<Integer> v1 = Sets.intersection(set, set2);
.difference(s1,s2)
Mutiset
无序可重复1 | //输出[study, dayday, up, good x 2] |
获取次数
1 | Set<String> ele = hms.elementSet(); |
Multimap
Key 可以重复,一个键对应一个Collection
1 | //输出: |
BiMap
双向map 键值都不能重复BiMap<String,String> map = HashBiMap.create();
key和val可以反转map.inverse()
Table<String,String,Integer> table = HashBasedTable.create();
获取条settable.cellSet()
拆分成两个一对多Student和Course生成StudentAndCourse
1 | class StudentAndCourse{ |
shuffle(list)
随机打乱reverse(list)
.sort()/(,Comparator c)
.swap
1 | public static void swap(List<?> list, int i, int j) { |
ArrayList: set返回旧值
1 | public E set(int index, E element) { |
rotate(list,int)
i移动到(i+d)%size
rotate1(list, distance);
: 数组实现,并且长度小于100RandomAccess
||list.size()
< ROTATE_THRESHOLD)
直接放在正确的位置上
理解:把0位放到正确位置(distance)后,将这个位置继续当作0位,继续移动distance步,直到i回到0位
1 | private static <T> void rotate1(List<T> list, int distance) { |
1 | reverse(list.subList(0, mid)); |
binarySearch
,max
,min
(遍历compare/compareTo)fill(List,o)
填充 (遍历调用set)frequency(c,o)
c中与o相等元素数量(遍历equals)replaceAll(list,old,new)
遍历equals,set只有vector/hashtable比较古老是安全的
synchronizedList(list)
…EmptyList
防空指针UnmodifiableCollection
重写了add、remove等方法,直接抛异常singletonMap
size=1disjoint(,)
没有相同元素返回trueaddAll(c,T...)
全部加入creverseOrder(Comparator<T> cmp)
返回比较器1 | //反转排序[5, 4, 3, 2, 1] |
public Enumeration<E> elements()
1 | Enumeration<Integer> es = v.elements(); |
1.迭代器接口 2.迭代器的实现(用构造函数传入(3))3.抽象类 4.具体类(return new迭代器)
public void forEach(Consumer<? super E> action)
Consumer
接口:void accept(T t);
1 | default void forEach(Consumer<? super T> action) { |
Set<Map.Entry<Integer,String>> enry = map.entrySet();
Collection<String> cl = map.values();
forEach(BiConsumer<? super K, ? super V> action)
.containsKey()
1 | for(Map.Entry<String,String> entry:map.entrySet()){} |
getOrDefault(Object key, V defaultValue)
不存在返回默认值
1 | return (((v = get(key)) != null) || containsKey(key))? v: defaultValue; |
V putIfAbsent(K key, V value)
不覆盖添加 原本的put覆盖并返回旧值
1 | V v = get(key); |
boolean remove(Object key, Object value)
保证key和val都有
1 | Object curValue = get(key); |
boolean replace(K key, V oldValue, V newValue)
V compute
对key位置上的kv对用BiFunction最后更新并返回计算后的值put(key, newValue);
1 | map.compute(1,(k,v)->v+="1"); |
merge
1 | map.merge(1,"222",(oldv,newv)->oldv+newv); |
1 | // Dummy value to associate with an Object in the backing Map |
不是同步的,支持 null 键和值
Ideally, under random hashCodes, the frequency of nodes in bins follows a Poisson distributionwith a parameter of about 0.5 on average for the default resizingthreshold of 0.75,
负载因子0.75的清空下,bin满足泊松分布(exp(-0.5) * pow(0.5, k) /factorial(k)).
落在0的桶的概率有0.6
用树存储冲突hash when bins contain enough nodes to warrant use
TREEIFY_THRESHOLD = 8;
1 | static final int hash(Object key) { |
实验:
1 | int a = (65535<<2)+1; |
put(K key, V value) {return putVal(hash(key), key
putVal
1 | n = (tab = resize()).length; |
putVal如果Node链表太长
1 | if (binCount >= TREEIFY_THRESHOLD - 1) //TREEIFY_THRESHOLD==8 |
TreeNode<K,V> extends LinkedHashMap.Entry<K,V>
65536(2^16)>>>16 ==1
&2^n-1
取模 2^n的table长不是素数很容易冲突i = (n - 1) & hash
插入位置 n-1=15是1111低位掩码高位归零>>>16
是int的高16位,低16与高16位^
,混合hash的高位低位key1=0ABC0000 & (16-1) = 0
(8个16进制数,共32位)key2=0DEF0000 & (16-1) = 0
hashcode的1位全集中在前16位。key相差很大的pair,却存放在了同一个链表
把hashcode的“1位”变得“松散”,比如,经过hash函数处理后,0ABC0000变为A02188B,0DEF0000变为D2AFC70
数据结构一样的名字不同:
hashtable:private transient Entry<?,?>[] table;
默认大小11
hashmap: transient Node<K,V>[] table;
TreeSet
实现了SortedSet
和NavigableSet
接口Comparable
接口或者构造函数中有ComparatorHashMap实现,用空对象占位
1 | private transient HashMap<E,Object> map; |
保持不重复 使用HashMap的 putVal
Comparatable
或传入Comparator
,会根据compare的值覆盖,去重NavigableSet
使用元素自然顺序排序,or 用Comparator标签:二分插入排序 gen 通配 equals 问题 city 二进制 也会 quic
原文地址:https://www.cnblogs.com/lijianming180/p/12286296.html