Java中集合及常用方法

0、集合接口及其实现类之间的关系

Java中集合及常用方法

  1. Collection接口

Collection的超级接口:Iterable接口。

1>Collection接口常用方法

操作

方法

add(E e)、addAll(Collection<? extends E> c)、

clear()、remove(Object o)、removeAll(Collection<?> c)、retainAll(Collection<?> c)、

 

contains(Object o)、containsAll(Collection<?> c)、

equals(Object o)、isEmpty()、size()

其他

hashCode()、

遍历

iterator()、foreach

2>Collection接口的方法使用举例(PracticeCollection.java)

Collection<String> aList = new ArrayList<>();

Collection<String> aList1 = new ArrayList<>();

Collection<String> aList2 = new ArrayList<>();

// 1.add

aList.add("Java Development");

aList1.add(" is very GOOD!");

aList2.add("Java Development");

// 2.addAll

aList.addAll(aList1);

// 3.clear

// aList1.clear();

// 4.contains

System.out.println(aList.contains("Java Development"));// true

System.out.println(aList.contains("Java"));// false

// 5.containsAll

System.out.println(aList.containsAll(aList2));// ture

// 6.equals

System.out.println(aList.equals(aList2));// false

// 7.hashCode

int hCode = aList.hashCode();

System.out.println(hCode);

// 8.isEmpty

System.out.println(aList.isEmpty());// false

// 9.iterator

System.out.println("********9**********");

for (Iterator<String> it = aList.iterator(); it.hasNext();) {

       System.out.println(it.next());

}

// 10.remove

System.out.println("********10**********");

System.out.println(aList.remove("Java Development"));// true

for (Iterator<String> it = aList.iterator(); it.hasNext();) {

       System.out.println(it.next());

}

// 11.removeAll

System.out.println(aList.removeAll(aList2));//ture

// 12.retainAll

System.out.println("********12**********");

System.out.println(aList.retainAll(aList2));

Iterator<String> it1 = aList.iterator();

while (it1.hasNext()) {

       System.out.println(it1.next());

}

// 13.size

System.out.println(aList.size());// 2

// 14.toArray

Object[] string = aList.toArray();

System.out.println(Arrays.toString(string));// 注意使用Arrays.toString方法

// foreach遍历

System.out.println("********foreach********** ");

for (Object object : aList) {

       System.out.println(object);

}

System.out.println("********iterator**********");

Iterator<String> it2 = aList.iterator();

while (it2.hasNext()) {

       System.out.println(it2.next());

}

3>Collection的遍历

[1]、Foreach快速遍历

System.out.println("********foreach********** ");

              for (Object object : aList) {

                     System.out.println(object);

              }

 

[2]、遍历器(Iterator)遍历

Iterator<String> it2 = aList.iterator();

while (it2.hasNext()) {

       System.out.println(it2.next());

}

性能较高的for循环遍历

for (Iterator<String> it = aList.iterator(); it.hasNext();) {

       System.out.println(it.next());

}

1.2 List接口

 

List接口表示有序(插入顺序)、不唯一的集合。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。

List 接口提供了 4 种对列表元素进行定位(索引)访问方法。

List 接口提供了特殊的迭代器,称为 listIterator,除了允许 Iterator 接口提供的正常操作外,该迭代器还允许元素插入和替换,以及双向访问。还提供了一个方法来获取从列表中指定位置开始的列表迭代器。

List的超级接口:Iterable、Collection

  1. List接口常用方法         

操作

方法(与超级接口Collection相同的不再写出

add(E e)、add(int index, E element)、

addAll(Collection<? extends E> c)、

addAll(int index, Collection<? extends E> c)

remove(int index)

set(int index, E element)

get(int index)、indexOf(Object o)、lastIndexOf、

lastIndexOf(Object o)

其他

subList(int fromIndex, int toIndex)

遍历

listIterator()、listIterator(int index)

 

  1. List接口的方法使用举例(PracticeList.java)

List<Integer> list = new LinkedList<>();

List<Integer> list1 = new LinkedList<>();

list.add(20);

list.add(30);

list1.add(60);

list1.add(80);

//1.add(带索引)

list.add(0,10);

//2.addAll(带索引)

list.addAll(0,list1);

//3.remove(带索引)

//list.remove(2);

//4.set

list.set(0, 100);//60-->100

//5.get

Integer integer1 = list.get(0);//100

//6.indexOf

int a = list.indexOf(60);//-1 为不存在该元素

int b = list.indexOf(30);//4

//7.lastIndexOf

int c = list.lastIndexOf(20);

//8.subList

List<Integer> list2 = new LinkedList<>();

list2 = list.subList(2, 5);//取出2~5的元素

//9.listIterator

System.out.println("**************listIterato顺序遍历r********");

ListIterator<Integer> it2 = list.listIterator();

while(it2.hasNext()) {

       System.out.println(it2.next());

}

System.out.println("**************listIterator倒序遍历********");

while (it2.hasPrevious()) {

       System.out.println(it2.previous());

}

 

 

  1. List的遍历

[1]、普通For循环利用index遍历

System.out.println("*******普通For循环遍历*********");

for (int i = 0; i < list.size(); i++) {

       System.out.println(list.get(i));

}

 

[2]、foreach快速遍历

System.out.println("*******快速遍历***********");

for(Object o :list) {

       System.out.println(o);

}

 

[3]、iterator遍历器遍历

System.out.println("*******iterator遍历器遍历***********");

for(Iterator<Integer> it3 = list.iterator();it3.hasNext();) {

       System.out.println(it3.next());

}

 

[4]、listIterator遍历器遍历

System.out.println("*******listIterator遍历器遍历***********");

for(ListIterator<Integer> it4 = list.listIterator();it4.hasNext();) {

       System.out.println(it4.next());

}

 

1.2.1 实现类ArrayList

List 接口的大小可变数组的实现。

此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

 

  1. ArrayList的数据结构

ArrayList是一种先行数据结构,底层数据接口是数组,数组不能扩容,而ArrayList可以通过Arrays.copyOf扩容。

 

  1. ArrayList常用方法

ArrayList常用方法与List基本一致。

特有:trimTosize();将此ArrayList实例的容量调整为列表的当前大小。

 

  1. ArrayList的遍历

ArrayList遍历与List遍历一样有四种:for循环遍历foreach遍历iterator遍历listIterator遍历

1.2.2 实现类LinkedList

LinkedList与ArrayList一样实现List接口,只是ArrayList是List接口的大小可变数组的实现,LinkedList是List接口链表的实现。基于链表实现的方式使得LinkedList在插入和删除时更优于ArrayList,而随机访问则比ArrayList逊色些。

LinkedList实现了 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。

 

1>LinkedList数据结构

底层数据结构是双向链表。

2>LinkedList常用方法

 

JDK1.5

JDK1.6

指定元素插入

offer(E e)末尾

offerFirst(E e)、offerLast(E e)

获取并不移除

peek ()

peekFirst()、peekLast()

获取并移除

poll()首

pollFirst()、pollLast()

 

3>LinkedList常用方法使用举例

public class LinkedListTest01 {

    public static void main(String[] args) {

        LinkedList<Double> list = new LinkedList<>();

        LinkedList<Double> list2 = new LinkedList<>();

        list.add(3.14);

        list.add(0, 1.414);

        list2.add(0, 1.732);

        list2.add(1, 1.738);

        System.out.println(list);

        System.out.println(list2);

        System.out.println("***********************");

        list.addAll(list2);

        System.out.println(list);

        // list.offer(1.732);

        // list.offerLast(1.732);

        // list.offerFirst(1.732);

        // System.out.println(list.peek());

        // System.out.println(list.peekFirst());

        // System.out.println(list.peekLast());

        // System.out.println(list.poll());

        // System.out.println(list.pollFirst());

        // System.out.println(list.pollLast());

        System.out.println(list);

    }

}

 

4>LinkedList的遍历

 

LinkedList的遍历有7种:迭代器遍历快速随机遍历foreach遍历pollFirst()方法遍历pollLast()方法遍历removeFirst()方法遍历removeLast()方法遍历

其中效率最高的是foreach遍历。

 

 

 

1.2.3 实现类Vector

       Vector与ArrayList的区别:

1. Vector产生与JDK1.0,ArrayList产生与JDK1.2;

       2. Vector线程安全,ArrayList线程不安全;

       3. ArrayList耗能低,性能高,Vector耗能高,性能低。

 

1.3 Set接口

1>Set数据结构

set是一个不包含重复元素的 collection。

注:如果将可变对象用作 set 元素,那么必须极其小心。如果对象是 set 中某个元素,以一种影响 equals 比较的方式改变对象的值,那么 set 的行为就是不确定的。此项禁止的一个特殊情况是不允许某个 set 包含其自身作为元素。

2>Set常用方法

Set的常用方法与Collection相似,不做介绍

  1. Set的遍历

Set的遍历有两种方式:foreach遍历iterator方法遍历

1.3.1 实现类HashSet

HashSet底层的数据结构是哈希表。

 

 

 

1> HashSet的遍历

HashSet有两种遍历方式为:foreach遍历iterator遍历

2>重写hashCode及equals方法

由于Set集合要求数据无序并且无重复,就需要先判断对象是否是同样内容再去添加,这样就导致要去重写hashCode以及equals方法,已实现对比对象的信息是否一致。

 

   @Override

   public int hashCode() {

      final int prime = 31;

      int result = 1;

      result = prime * result + ((Name == null) ? 0 : Name.hashCode());

      result = prime * result + age;

      result = prime * result + ((sex == null) ? 0 : sex.hashCode());

      long temp;

      temp = Double.doubleToLongBits(weight);

      result = prime * result + (int) (temp ^ (temp >>> 32));

      return result;

   }

 

   @Override

   public boolean equals(Object obj) {

      if (this == obj)

         return true;

      if (obj == null)

         return false;

      if (getClass() != obj.getClass())

         return false;

      Person other = (Person) obj;

      if (Name == null) {

         if (other.Name != null)

            return false;

      } else if (!Name.equals(other.Name))

         return false;

      if (age != other.age)

         return false;

      if (sex != other.sex)

         return false;

      if (Double.doubleToLongBits(weight) != Double.doubleToLongBits(other.weight))

         return false;

      return true;

   }

 

 

1.3.2 实现类LinkedHashSet

1>LInkedHashSet数据结构

底层为哈希表+链表,用于维持次序(插入次序),

其常用方法与HashSet一致。

优点:查找速度更快、缺点:数据结构复杂。

2>LinkedHashSet的遍历

LInkedHashSet有两种遍历方法:foreach遍历、Iterator遍历器遍历

1.3.3 实现类TreeSet

1>TressSet数据结构

TreeSet:二叉树(红黑树)的存储结构,存入数据以自然顺序排列(内部排序)。

2>TreeSet常用方法

操作

方法

 

 

 

ceiling(E e)、first()、floor(E e)、higher(E e)、last()、lower(E e)、

pollFirst()、pollLast()、

subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)、

其他

 

遍历

descendingIterator()、iterator()

3>TreeSet的遍历

TreeSet的遍历有三种方式:foreach遍历、Iterator遍历器遍历、descendingIterator方法降序遍历。

[1]、foreach遍历

System.out.println("************foreach******************");

      for (Integer integer : ts) {

         System.out.println(integer);

      }

 

[2]、Iterator遍历器遍历

System.out.println("****************Iterator***************");

      for(Iterator<Integer> iterator = ts.iterator();iterator.hasNext();) {

         System.out.println(iterator.next());

      }

 

[3]、descendingIterator方法降序遍历

System.out.println("***********descendingIterator*********");

      for (Iterator<Integer> iterator = ts.descendingIterator(); iterator.hasNext();) {

         System.out.println(iterator.next());

      }

4>有关实现comparable接口并实现CompareTo接口

对于TreeSet中保存的自定义类型对象,此时就需要实现Comparable接口并实现CompareTo方法。

示例:

public class Person implements Comparable<Person>

@Override

   public int compareTo(Person o) {

     

      return this.Name.compareTo(o.Name);

   }

示例2:外部比较器

TreeSet<Person1> ts  = new TreeSet<>(new Comparator<Person1>() {

         @Override

         public int compare(Person1 o1, Person1 o2) {

            return o1.getAge()-o2.getAge();

         }

      });

 

  1. Map<K,V>接口

类型参数:

K:-此映射所维护的键的模型

V:-映射值的类型

将键映射到值得对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

Map接口提供三种collection视图,允许以键集值集、或键-值映射关系的形成查看某个映射的内容。映射顺序定义为迭代器在映射的collection视图上返回其元素的顺序。某些映射实现可以明确保证其顺序,如TreeMap类;另一些映射实现则不保证顺序,如HashMap类。

实现类:HashMap、Hashtable、LinkedHashMap、TreeMap。

key通过Set存储;value通过Collection存储。

1>Map接口常用方法

操作

方法

put(K key, V value)、

clear()、remove(Object key)、

 

containsKey(Object key)、containsValue(Object value)、

get(Object key)、size()

其他

 

遍历

entrySet()、keySet()

 

2>Map的遍历

Map的遍历有两种方法,分别为使用entrySet()方法、keySet()方法。

[1]、使用keySet()方法得到key值,并通过key值得到对应的value值

示例:

System.out.println("***iterator//keySet()方法->得到key->通过key遍历***");

      for(Iterator<Integer> iterator = hm.keySet().iterator();iterator.hasNext();) {

         int key = iterator.next();//得出键k

         System.out.println(key+":"+hm.get(key));//得出key对应的value

      }

 

[2]、利用entrySet()方法实现遍历

entrySet()方法会有一个Set<Map.Entry<K,V>>类型的返回值,通过该返回值读取键值对,可以实现效率更高的遍历。

示例1:

System.out.println("***iterator//Map.Entry接口+entrySet方法+foreach实现遍历①***");

      Set<java.util.Map.Entry<Integer, Integer>> entrySet= hm.entrySet();

      for(java.util.Map.Entry<Integer, Integer> entry :entrySet) {

         System.out.println(entry.getKey()+":"+entry.getValue());

      }

 

示例2:

System.out.println("***iterator//Map.Entry接口+entrySet方法+for遍历②***");

      for(Iterator<java.util.Map.Entry<Integer, Integer>> iterator = entrySet.iterator();iterator.hasNext();) {

         System.out.println(iterator.next());

      }

 

示例3:

System.out.println("***iterator//Map.Entry接口+entrySet方法+for遍历③***");

      for(Iterator<java.util.Map.Entry<Integer, Integer>> iterator = entrySet.iterator();iterator.hasNext();) {

         java.util.Map.Entry<Integer, Integer> entry2 = iterator.next();

         System.out.println(entry2.getKey()+":"+entry2.getValue());

      }

 

    1. 实现类HashMap

基于哈希表的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键。(除了非同步和允许使用null之外,HashMap与Hashtable大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

HashMap的实例有两个参数影响其性能,初始容量加载因子容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子是哈希表在其容量自动增加之前可以达到多慢的一种尺度,当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对哈希表进行rehash操作(重建内部数据结构),从而哈希表将具有大约两倍的桶数。

此实现并不是同步的

key通过HashSet存储、value通过Collection存储

2.2 实现类Hashtable

线程安全版的HashMap,性能逊于HashMap。

HashMap源于JDK1.2;Hashtable源于JDK1.0;

HashMap线程不安全,Hashtable线程安全;

HashMap耗能低,速度快,Hashtable耗能高,速度慢。

2.3 实现类LinkedHashMap

key通过LinkedHashSet存储、value通过Collection存储

2.4 实现类TreeMap

key通过TreeMap存储、value通过Collection存储

性能比较

Java中集合及常用方法