2,Java中的数据结构

 

1,字符串(String)
···String为特殊的引用类型,不可变。
···经常使用实例方法:
    获取子串:substring(start, end);
    获取索引:indexOf(char);
    获取字符:charAt(index);
···经常使用静态方法:
    格式字符串:String.format("%s", 12);
    转为字符串:String.valueOf();
    格式拼接:String.join(", ", list);
···扩展:
    StringBuilder:可变对象,用来高效拼接字符串。
    StringBuffer:是StringBuilder的线程安全版。
··· 注意:
    · String.valueOf()比str.toString()安全;
    · 常量池默认只会在编译期对字符串字面量和常量进行优化;能够经过"".intern()方法在运行期将堆中的字符串放入常量池。
 
2,数组
···能够经过索引访问,初始化必须指定大小,而且不可改变。
···经常使用方法:
    排序:Arrays.sort(int[]);
    转list:Arrays.asList(int[]);  // 返回的list是固定长度的,不能改变。最好用for一个个转。
    扩容:Arrays.copyOf(int[], newlenght);
    填充:Arrays.fill(int[], int);
···转Set:
    Set<T> set = new HashSet<>(Arrays.aslist(int[]));
    因为Set构造方法的参数必须继承自Collection接口,因此要先把数组转list。
···逆序排序:
    Integer[] a = new Integer[5];
    Comparator<Integer> cmp = new Comparator<>() {
    @Override
    public int compare(Integer o1, Integer o2) {
           return o2 - o1;
        }
    };
Arrays.sort(a, cmp);
 
 
3,列表(List)
···实现类:
    ArrayList:数组实现;LinkedList:链表实现;Vector:线程安全;
···经常使用实例方法:
    根据索引查找:get(index);
    判断是否存在:contains(obj);
    查找索引:indexOf(obj);
    排序:sort(Comparator);
    合并两个list:addAll(list);
    转数组:toArray(new Obj[]{});
···经常使用静态方法:
    排序:Collections.sort(list,Comparator);
    逆序:Collections.reverse(list);
    求最值:Collections.max(list); Collection.min(list);
    浅拷贝:Collections.copy(dest, src);  // dest的实际长度必须大于或等于src
···List的stream方法:
    List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3));
    List<Integer> a = list.stream().map(x-> x*2).collect(Collectors.toList());
 
4,集合(Set)
···实现类:
    HashSet:数组实现,无序(有规律);TreeSet:自动排序;LinkedHashSet:链表实现,保持原序;
···注意:
     因为Set也继承自Collection接口,因此其余方法与List相似,底层实现也是Hash,至关因而没有value的Map。
 
5,键值对(Map)
···实现类:
    HashMap:数组实现,无序;TreeSet:根据Key排序;LinkedHashMap:保持原序;
···经常使用实例方法:
    得到全部Key:KeySet(),返回值为Set类型;
    得到全部Value:values();
···排序:
    先把map.entrySet()放入list,再用Collection.sort(list, Compartor);对list的value排序,再把list放入LinkedHashMap中便可。
···注意:
    HashMap中的key和value均可觉得null。而Hashtable不能够。
··· *底层理解*:
·大体实现:HashMap底层使用的是哈希表加链表。输入的key是对象的hashCode;哈希函数是hashCode & (lenght - 1);哈希冲突的解决办法是使用链表保存哈希值相同的对象。当链表长度大于8时使用红黑树保存(jdk1.8开始);查询时先经过对象的hashCode找到对象在数组的位置,而后经过equals()遍历链表,找到目标对象。
·细节优化: 哈希函数hashCode & (lenght-1)是位运算, 比模运算快不少;因为哈希函数是hashCode & (lenght-1),因此当哈希表的长度lenght是2的幂次方时哈希表的利用率最高,哈希冲突也就越小,好比:当lenght为15时hashCode & 14,hashCode & 1110 时第一位0与上任何数都为0,因此哈希函数的结果永远不会出现第一位为1的状况,即000一、0011等位置上永远不会存值,致使实际利用长度变小,也就越容易出现哈希冲突。
·扩容:因为数组的长度固定(默认是16),因此当实际长度超过最大长度的75%时,须要对哈希数组进行扩容,增大为原最大长度的2倍,并将旧哈希表的元素从新计算哈希值放入新的哈希表中,很是消耗性能,因此在初始化时尽可能指定长度,以免扩容。例如:须要存放1000个元素时,指定初始化大小为2048(1024*75%<1000因此还会扩容,所以选择2048)。
 
6,包装类型
···概念:包装类型是把基本类型包装为引用类型,把基本类型转为引用类型称为装箱,反之为拆箱。
···优势:
    · 与基本类型相比,包装类型提供了大量实用的方法。
    · 在项目中尽可能使用包装类型,由于包装类型的null和0能够区分有值和没值。
 
注意事项
    · a=a+12 与 a+=12 的区别: 当a为short时,使用会把12当成int类型;而使用 += 时,会把右边的字面量12转为左边变量的类型。
    · 进制显示:二进制(0b):int b=0b101;  八进制(0):int e=032;  十六进制(0x):int h=0xf1;
    · Boolean类型:boolean类型能够进行 位运算,而且运算符优先级:>, &, &&,且位运算符与逻辑运算符的效果同样,可是不会短路。
相关文章
相关标签/搜索