集合、数据结构、时间复杂度
1、集合
1.1 概述
java集合分为三种类型,List、set和Map。List有序,可以重复。Set无序不重复。Map是Key-value对类型,其中Key具有set的特点。
1.2 List
List java中有ArrayList和LinkedList两种实现。
-
ArrayList
通过数组来实现,擅长读操作,有容量概念,扩容发展50%。
-
LinkedList
内部通过链表实现,通过指针实现,检索的对象时从两头检索,看索引位于哪个半段范围中。内部存放了首尾两个节点,元素通过node连接在一起。Node由item 、 prev、 next构成,检索最坏情况不会超过半数。
-
性能评测
Arraylist LinedList 结论 写(100w) 90,255ms 40ms 200x 读(5wth) 0.036,538ms 0.637,157ms 20x
1.3 Map
map是通过key-value关联起来的映射构成的集合。其中key具有set的特点。java中Map有HashMap和TreeMap。
-
HashMap
-
内部通过数组+链表实现
class HashMap{ // transient Node<K,V>[] table; // static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; } }
-
Hashmap put流程为
int newhash = 获取key的新hash; 通过新hash定位桶的坐标; if(坐标位为空?){ 在该位置创建节点 ; } else{ if(新hash相同?){ if(key是同一对象?){ key相同,覆盖value的值。 } else{ if(key的equals是否相同?){ key相同,覆盖value } else{ 继续寻找下一个Node; } } } else{ 继续找下一个Node; } }
-
新hash计算方法
旧hash码的高低16位做异或运算,实现计算结果的更加分散,高位右移是想让更多的特征值参与进来。
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
-
-
TreeMap
内部通过红黑二叉树实现,具体见我的数据结构一文。
作业
-
设计一个类Person含有height、weight、age和blood是整数属性,实现hashcode方法,将四个属性编排到一个整数中作为hashcode.
答:
class Person{ private int height ; private int weight ; private int age ; private int blood ; public int hashCode(){ return (height & 0xff) << 24 | (weight & 0xff) << 16 | (age & 0xff) << 8 | (blood & 0xff) << 0 ; } public boolean equals(Object o){ if(o == null || o.getClass() != Person.class) return false ; return this.hashCode() == o.hashCode() ; } }
-
折半查找的时间复杂度问题
折半查找的时间复杂度为(O(log_{2}n)),具体过程见时间复杂度一文。
-
99乘法表的时间复杂度
99乘法表的时间复杂度为(O(n^2)) ,具体过程见时间复杂度一文。
-
两个n阶方阵的乘积的时间复杂度
两个n阶方阵的乘积的时间复杂度为(O(n^3)) ,具体过程见时间复杂度一文。
-
红黑树依次存放1,2,3,4,5,6,7,8做为key,给出树的最终结构。
树结构为: