java数据结构

java数据类图:

 

常用的方法:

 


类 Arrays 的 static <T> List<T>asList(T... a);
返回一个T的List
类 Collections的 static <T> booleanaddAll(Collection<? super T> c, T... elements)
将后面的多个参数添加到前面的collection中去
类Collection本身也有一个boolean addAll(Collection<? extends E> c)
将集合为c的加入到自身中去


存储方式

ArrayList和LinkedList都是按插入元素的顺序保存的,ArrayList随机访问效率高于LinkedList,并且插入/删除代价比极大;而LinkedList插入删除比较好,但是随机性访问比前者低
LinkedList功能特点更多,可以把它像堆和栈一样用,其提供了很多有特点的方法,addFirst,addLast,getFirst,getLast,pop,push,pollFirst,pollLast等

vector大部分功能和ArrayList一样,不同的是vector是线程安全的,但是此开销大,一般使用较少

在扩容方面,ArrayList当内存不足时,是扩容之前大小一半在加一,vector直接扩大一倍

LinkedList当栈用的方法:
pop()  push()  peek()返回栈顶元素但不删除  peekfirst() peekLast分别访问栈顶和栈底 empty()


LinkedList当队列Queue的方法:
LinkedList实现了队列接口Queue,可以像队列一样使用,offer()队尾添加   remove()/poll()队首删除并返回手元素(空时前者会抛出异常后者返回null) peek和element都是返回队首元素并且不删除(空时,peek返回null,element抛出异常)

Set无须集合的存储结构,不存储相同数据,主要是通过hashCode来判断元素是否相同

HashSet内部实质是一个HashMap,key存储元素,value存储相同的Object引用,当存入元素时,先判断hashcode是否相同,不等时存入map,相等时在判断key的equals方法,不等时就放到这个元素单链表后面;

TreeSet是有序的数据集合,这个序需要你为TreeSet提供Comparable对象,或者存储元素实现Comparable接口

//元素实现Comparable
TreeSet ts = new TreeSet();
ts.add(new Person("aa", 20, "男"));

class Person implements Comparable {
    @Override
	public int compareTo(Object obj) {}
}

//Treeset传入Comparable对象
TreeSet ts = new TreeSet(new MyComparator());
class MyComparator implements Comparator {
 
	public int compare(Object o1, Object o2) {
	}
 
}

LinkedHashSet则是按照顺序存储


HashSet和TreeSet和LinkedHashSet存储则不同,不会保存重复的数据,HashSet存储比较复杂,但是获取元素是最快的;如果要按顺序存储的话建议使用TreeSet和LinkedHashSet

set相对于Collection,没有多余的方法,只是行行为不同,重写;而Set数据元素更多的用来测试归属性contains(Object o)

以上四个多线程访问都是不安全的,多线程编程中要做好并发处理,或者用辅助类Collections的public static <T> Collection<T> synchronizedCollection(Collection<T> c)等发放创建对象实例


HashMap/TreeMap和LinkedhashMap通过键值对保存数据,和上面一样,HashMa但是获取元素最快,TreeMap通过比较结果升序排列,LinedMap则是按添加顺序保存元素

HashMap:

内部存储结构是一个数组加横向的单链表,key-value形式存放,根据key的hashcode存储,key运行存放null值

TreeMap:

内部红黑树结构,一种自平衡的二叉树,查找效率在O(logN),N是元素的个数,TreeMap也是有序集合结构,需要提供Comparable对比接口;

Map<String, String> map = new TreeMap<String, String>(new Comparator<String>() {
    public int compare(String obj1, String obj2) {
        return obj2.compareTo(obj1);// 降序排序
    }
});
map.put("a", "c");
map.put("b", "b");
map.put("c", "a");
 
for (String key : map.keySet()) {
    System.out.println(key + " :" + map.get(key));
}

HashTable:

与HashMap类似,但是它支持线程同步的,所以效率较低,同一时刻只允许一个线程去访问,并且key-value允许为null

LinkedHashMap:

顺序存储,按照插入顺序进行存储,可以使用iterator迭代器进行迭代,但是效率肯定是比hashmap低,原因就是底层链表存储结构

迭代器:

只要一个类实现了Iterable接口并实现它的iterator方法,他就会获得一个Java标准的iterator,可以进行迭代操作

 

Package java.lang;

import java.util.Iterator;
public interface Iterable<T> {
Iterator<T> iterator();
}


Java的AbstractCollections类实现了该接口,所以其子类list、set都支持iterator迭代


Iterator提供了对数据结构的遍历与数据结构本身分离,不需要去关心数据结构底层是如何实现的,只需用hasnext() next去执行迭代器即可,但是只能单向遍历


ListIterator属于Iterator的子类,但功能更强大,支持双向遍历hasNext()/hasPrevious(),通过next()/previous()获取元素,还可以查看前一个/后一个元素的位置序号previousIndex()/nextIndex(),更能够修改元素set();还能够插入/删除元素,remove  insert(双向迭代只能用于List)


Map数据类型迭代:
Map没有显示Iterator接口,但Map的方法entrySet()将键值对返回成一个set则可以用foreach来实现遍历

Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {  
  
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  


}  

foreach增强型for循环,此冲类型迭代使用,比较简洁,你只需要知道集合内部的数据元素类型就可以进行迭代,你不需要知道集合的起点和终点,使用快捷

相比于iterator迭代的话,foreach缺点就是你在循环过程中使用集合的remove删除元素,有可能导致出错,因为集合size变了;而iterator则支持在迭代过程中删除,使用iterator的remove删除,他会对该元素记录一个删除的标志位,下次你在使用时,就不会出错了

遍历性能问题:

对于array类型的集合,使用for循环快一些,直接顺序读取

对于list类型集合,iterator遍历链式要快一些

什么时候用for什么时候用iterator呢?

从数据结构上,for循环中采用get方式进行随机访问,这个时候数组类型的arrayList适合

而iterator更多的是采用链式next/previous一个一个顺序访问,这种适合于linkedlist进行访问

 

 PriorityQueue优先级队列:
在数据插入offer时,会将数据插入到合适的位置,从而保证取出peek poll的数据优先级是最高的(数字默认是越小越高,字符则越小越高 空格更高)


容器中的两个辅助类:
Collections和Arrays
他们属于工具类,提供了很多静态方法辅助Collection和MAP,并且不能实例化;

posted @ 2015-09-23 22:31  帅气好男人_jack  阅读(4)  评论(0编辑  收藏  举报  来源