欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java的数据结构

程序员文章站 2022-06-05 19:28:23
...

Java中有几种常用的数据结构,主要分为Collection和map两个主要接口

Java的数据结构

 

Collection--->Collections   

List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
Set下有HashSet,LinkedHashSet,TreeSet
List下有ArrayList,Vector,LinkedList
Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
Collection接口下还有个Queue接口,有PriorityQueue类

1、List(接口)

List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下 >标)来访问List中的元素,这类似于Java的数组

Vector 

基于数组(array)类型的list集合,其实就是封装了一些数据不具备的功能方便程序员使用,
所以它还是难易避免数组的显示,同时性能也不可能超过数组,所以更多的情况下还是使用数组
,Vector是sychronized的,这也是Vector和arrayList的重要区别

ArrayList
 

同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。
所以在性能上要比Vector好一些,但是当运行到多线程环境中时,
可需要自己在管理线程的同步问题

LinkedList

LinkedList不同于前面两种List,它不是基于数组的,所以不受数组性能的限制。 
它每一个节点(Node)都包含两方面的内容: 
1.节点本身的数据(data); 
2.下一个节点的信息(nextNode)。 
所以当对LinkedList做添加,删除动作的时候就不用像基于数组的ArrayList一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了,这是LinkedList的优势。

总结:
 

ArrayList,Vector主要区别为以下几点:
(1):Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比,但是Vector比ArrayList更安全;
(2):ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍;
(3):Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数。

ArrayList,LinkedList区别:

1、LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。
另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、
队列和双向队列使用
2、ArrayList和Vector底层是用数组实现的,因此可以用序号下标来访问他们,查找的效率高,一般数组的大小比要插入的数据大数量要大。

ArrayList、LinkedList、Vector 三者:
ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高

2、map

Java的数据结构

Map接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。

TreeMap是有序的,HashMap和HashTable是无序的。

TreeMap是按照Key的自然顺序或者Comprator的顺序进行排序。
在实现原理上LinkedHashMap是双向链表,TreeMap是红黑树。TreeMap还有个好兄弟叫TreeSet,
实现原理是一样的

 public static void main(String args[]) {
        HashSet<String> hashSet = new HashSet<>();
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        TreeSet<String> treeSet = new TreeSet<>();

        for (String data : Arrays.asList("B", "E", "D", "C", "A")) {
            hashSet.add(data);
            linkedHashSet.add(data);
            treeSet.add(data);
        }

        //不保证有序
        System.out.println("Ordering in HashSet :" + hashSet);

        //FIFO保证安装插入顺序排序
        System.out.println("Order of element in LinkedHashSet :" + linkedHashSet);

        //内部实现排序
        System.out.println("Order of objects in TreeSet :" + treeSet);


    }

运行结果:
Ordering in HashSet :[A, B, C, D, E] (无顺序)
Order of element in LinkedHashSet :[B, E, D, C, A] (FIFO插入有序)
Order of objects in TreeSet :[A, B, C, D, E] (排序)

下面列出treeMap的一些方法:

void clear():它从地图中删除所有键值对。
void size():返回此映射中存在的键值对的数量。
void isEmpty():如果此映射不包含键 - 值映射,则返回true。
boolean containsKey(Object key):'true'如果地图中存在指定的键,则返回。
布尔的containsValue(对象键):它返回'true'如果一个指定的值被映射到地图上的至少一个键。
Object get(Object key):它检索value指定的映射key,如果此映射不包含键的映射,则返回null。
Object remove(Object key):它从地图中删除指定键的键值对(如果存在)。
比较器比较器():它返回用于对此映射中的键进行排序的比较器,如果此映射使用其键的自然顺序,则返回null。
Object firstKey():它返回树映射中当前的第一个(最少)键。
Object lastKey():它返回树映射中当前的最后一个(最大)键。
Object ceilingKey(Object key):返回大于或等于给定键的最小键,如果没有这样的键则返回null。
Object higherKey(Object key):返回严格大于指定键的最小键。
NavigableMap descendingMap():它返回此映射中包含的映射的逆序视图。


Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。

这就意味着:

Hashtable是线程安全的,HashMap不是线程安全的。
HashMap效率较高,Hashtable效率较低。
如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。 查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。

HashTable源码如下:

 public Hashtable(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);

        if (initialCapacity==0)
            initialCapacity = 1;
        this.loadFactor = loadFactor;
        table = new Entry<?,?>[initialCapacity];
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    }
    /**
     * Returns an enumeration of the values in this hashtable.
     * Use the Enumeration methods on the returned object to fetch the elements
     * sequentially.
     *
     * @return  an enumeration of the values in this hashtable.
     * @see     java.util.Enumeration
     * @see     #keys()
     * @see     #values()
     * @see     Map
     */
    public synchronized Enumeration<V> elements() {
        return this.<V>getEnumeration(VALUES);
    }

    /**
     * Tests if some key maps into the specified value in this hashtable.
     * This operation is more expensive than the {@link #containsKey
     * containsKey} method.
     *
     * <p>Note that this method is identical in functionality to
     * {@link #containsValue containsValue}, (which is part of the
     * {@link Map} interface in the collections framework).
     *
     * @param      value   a value to search for
     * @return     <code>true</code> if and only if some key maps to the
     *             <code>value</code> argument in this hashtable as
     *             determined by the <tt>equals</tt> method;
     *             <code>false</code> otherwise.
     * @exception  NullPointerException  if the value is <code>null</code>
     */
    public synchronized boolean contains(Object value) {
        if (value == null) {
            throw new NullPointerException();
        }

        Entry<?,?> tab[] = table;
        for (int i = tab.length ; i-- > 0 ;) {
            for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {
                if (e.value.equals(value)) {
                    return true;
                }
            }
        }
        return false;
    }

Hashtable不允许null值,HashMap允许null值(key和value都允许)
父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap

3、set分为HashSet 、LinkedHashSet、TreeSet

HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals()

LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一

TreeSet
底层数据结构是红黑树。(唯一,有序)
1. 如何保证元素排序的呢?
自然排序
比较器排序
2.如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
  public static void main(String args[]) {
        HashSet<String> hashSet = new HashSet<>();
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        TreeSet<String> treeSet = new TreeSet<>();

        for (String data : Arrays.asList("B", "E", "D", "C", "A")) {
            hashSet.add(data);
            linkedHashSet.add(data);
            treeSet.add(data);
        }

        //不保证有序
        System.out.println("Ordering in HashSet :" + hashSet);

        //FIFO保证安装插入顺序排序
        System.out.println("Order of element in LinkedHashSet :" + linkedHashSet);

        //内部实现排序
        System.out.println("Order of objects in TreeSet :" + treeSet);


    }

运行结果:
Ordering in HashSet :[A, B, C, D, E] (无顺序)
Order of element in LinkedHashSet :[B, E, D, C, A] (FIFO插入有序)
Order of objects in TreeSet :[A, B, C, D, E] (排序)

 

相关标签: java