参考文章:浅谈Java中的Set、List、Map的区别

     Java 7 Collections详解

java中集合分为三类:

  1. Set(集)
  2. List(列表)
  3. Map(映射)

Set和List继承自Collection借口,Collection是基本的集合借口,声明适用于JAVA集合。

Collection定义接口函数:

  • boolean add(Object o)      :向集合中加入一个对象的引用 
  • void clear():删除集合中所有的对象,即不再持有这些对象的引用 
  • boolean isEmpty()    :判断集合是否为空 
  • boolean contains(Object o) : 判断集合中是否持有特定对象的引用 
  • Iterartor iterator()  :返回一个Iterator对象,可以用来遍历集合中的元素 
  • boolean remove(Object o) :从集合中删除一个对象的引用 
  • int size()       :返回集合中元素的数目 
  • Object[] toArray()    : 返回一个数组,该数组中包括集合中的所有元素,关于:Iterator() 和toArray() 方法都用于集合的所有的元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组。 

1. Set是最简单的集合,集合中的对象不按特定方式排序,并且没有重复对象,Set接口主要实现两个类:

  • HashSet, 按照哈希算法存取集合中对象,速度较快
  • TreeSet,实现了SortedSet接口,可以对集合中对象进行排序Set存放对象的引用,没有重复对象.

典型HashSet用例如下:

    static void findDups() {
String[] str = {"d", "b", "c", "a", "d"};
Set<String> s = new HashSet<String>();
for (String a : str)
if (!s.add(a))
System.out.println("Repeated: " + a);
System.out.println("HashSet extends from Set: " + s);
System.out.println("Unique elements: " + s.size()); s.removeAll(Collections.singleton("d"));
System.out.println(s); s.addAll(Collections.singleton("w"));
System.out.println(s); String newStr = s.toString();
System.out.println(newStr);
}

HashSet和TreeSet性能差距,可以看如下代码分析,插入方面,Hash大概比后者快4倍:

 final StopWatch stopwatch = new StopWatch();
stopwatch.start(); Set set = new HashSet();
String s1 = new String("Hello");
String s2 = s1;
String s3 = new String("world");
// Stop watch split
stopwatch.split();
System.out.println("HashSet create: " + stopwatch.getSplitNanoTime()); // HashSet add value
set.add(s1);
set.add(s2);
set.add(s3);
// Stop watch split
stopwatch.split();
System.out.println("HashSet add: " + stopwatch.getSplitNanoTime()); Set set2 = new TreeSet();
// Stop watch split
stopwatch.split();
System.out.println("TreeSet create: " + stopwatch.getSplitNanoTime());
set2.add(s3);
set2.add(s3);
set2.add(s1);
// Stop watch split
stopwatch.split();

2. List 特征是线性存储元素,集合中可以存在重复对象。

2.1 List接口主要实现类包括:

ArrayList:代表长度可以改变的数组,可以对元素进行随机访问,往list总插入删除元素较慢。

LinkedList 采用链表数据结构实现,插入和删除速度较慢,访问速度慢。

在搜索频繁的情况下,选择使用ArrayList;插入删除频繁的情况下,选择使用ListArray。值得提一下的的是,从java2开始,Vector向量改进为可以实现List。除了继承Collection, List实现了很多自带函数,例如截取函数。

  •     int indexOf(Object o);
  •     int lastIndexOf(Object o);
  •     ListIterator<E> listIterator();
  •     ListIterator<E> listIterator(int index);
  •     List<E> subList(int from, int to);

List 常用操作如下:

  static <E> void swap(List<E> a, int i, int j) {
E temp = a.get(i);
a.set(i, a.get(j));
a.set(j, temp);
} static void shuffle(List<?> list, Random rnd) {
for (int i = list.size(); i > 1; i--){
int rndNum = rnd.nextInt(i);
//System.out.println(rndNum);
try{
swap(list, i - 1, rndNum);
} catch (IndexOutOfBoundsException exc){
exc.printStackTrace();
}
}
} static void ListOpts() {
List<String> list = new ArrayList<String>();
String[] str = {"a","b","c","d","e","f"};
for (String a : str) {
list.add(a);
}
List<String> list1 = new ArrayList<String>(Arrays.asList(str));
shuffle(list, new Random());
shuffle(list1, new Random());
System.out.println(list);
System.out.println(list1); int indexOf = list.indexOf("e");
int indexOf1 = list1.indexOf("e");
System.out.println(indexOf);
System.out.println(indexOf1);
}

2.2 此外,List还有ListIterator这个增强型Iterator,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator 没有当前元素;它的光标位置 始终位于调用 previous() 所返回的元素和调用 next() 所返回的元素之间。长度为 n 的列表的迭代器有 n+1 个可能的指针位置(如图,长度为4的列表的迭代器有5个可能的指针位置)。

逆序访问List实现代码如下:

    static <E> void ListIterator(List<E> list) {
for (ListIterator<E> it = list.listIterator(list.size()); it.hasPrevious();) {
E t = it.previous();
System.out.print(t + " ");
}
}

同时ListIterator提供Set和Add两种方法,下面代码演示如何将List中元素替换为其他值:

   static <E> void ListReplace(List<E> list, E val, E newVal) {
for (ListIterator<E> it = list.listIterator(); it.hasNext(); ) {
if (val == null ? it.next() == null : val.equals(it.next()))
it.set(newVal);
}
}

当然,我们还可以将某个元素替换位一系列元素:

    static <E> void ListReplaceWithList(List<E> list, E val, List<? extends E> newVals) {
for (ListIterator<E> it = list.listIterator(); it.hasNext(); ) {
if (val == null ? it.next() == null : val.equals(it.next())){
it.remove();
for (E e : newVals)
//System.out.println(e);
it.add(e);
}
}
}

可以这样搜索List表里的指定元素:

res = list.subList(fromIndex, toIndex).indexOf(object);

如果返回-1表示没有找到,否则返回指定元素在List中下标。

2.3 任意一个操作List的多肽算法,如replace和shuffle方法,都是与字表打交道的。这里给出一个使用subList的多肽方法,使用这个方法来处理经典发扑克牌的问题。首先,先假设只给一个人发牌(hand),扑克牌堆用deck表示,那么发n张牌就可以看做从deck表的尾部截取n个元素的子List。代码如下:

    static <E> List<E> dealHand(List<E> deck, int n) {
int deckSize = deck.size();
List<E> handView = deck.subList(deckSize - n, deckSize);
System.out.println("handView: " + handView);
List<E> hand = new ArrayList<E>(handView);
handView.clear();
return hand;
}

注意:我们操作从sublList获取List时候,例如运行clear,父List同样会清空。

Ok, 接下来我们模拟发牌行为,代码如下:

    static <E> void dealing(List<E> deck, int numHands, int cardsPerPerson) {
Collections.shuffle(deck);
if (numHands * cardsPerPerson > deck.size()){
System.out.println("Too many hands to play!");
return ;
}
for (int i = 0; i < numHands; i++){
System.out.println(dealHand(deck, cardsPerPerson));
}
}

最后贴上原文作者链接图:

java集合分析(转载)的更多相关文章

  1. Java集合分析

    Java集合分析 前言 从开始接触Java的时候, 就在强调的一个重要版块, 集合. 终于能够开始对它的源码进行分析, 理解, 如果不懂得背后的思想, 那么读懂代码, 也仅仅是读懂了 if else ...

  2. Java集合—Queue(转载)

    Queue用于模拟队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器.新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素.通常,队列不允许随机访问队列中的元素 ...

  3. Java集合—List(转载)

    本篇文章将集中介绍了List集合相比Collection接口增加的一些重要功能以及List集合的两个重要子类ArrayList及LinkedList. 一.List集合 List作为Collectio ...

  4. Java集合—Set(转载)

    Set集合中包含了三个比较重要的实现类:HashSet.TreeSet和EnumSet.本篇文章将重点介绍这三个类. 一.HashSet类 HashSet简介 HashSet是Set接口的典型实现,实 ...

  5. java 集合(转载)

    一.集合与数组 数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用. 集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用. ...

  6. Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 [ 转载 ]

    Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 @author Trinea 原文链接:http://www.trinea.cn/android/arrayl ...

  7. Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

    概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Ja ...

  8. Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  9. Java 集合 fail-fast机制 [ 转载 ]

    Java 集合 fail-fast机制 [转载] @author chenssy 摘要:fail-fast产生原因.解决办法 在JDK的Collection中我们时常会看到类似于这样的话: 例如,Ar ...

随机推荐

  1. python <tab>自动补全

    1.获取python目录[我使用的是64位ubuntu系统] [~$]python Python 2.7.3 (default, Apr 10 2013, 06:20:15) [GCC 4.6.3] ...

  2. SQL Server索引进阶:第十三级,插入,更新,删除

    在第十级到十二级中,我们看了索引的内部结构,以及改变结构造成的影响.在本文中,继续查看Insert,update,delete和merge造成的影响.首先,我们单独看一下这四个命令. 插入INSERT ...

  3. <转>LINQ To SQL 语法及实例大全

    一篇很全很强大的linq to sql 总结 来源:http://blog.csdn.net/pan_junbiao/article/details/7015633 目录(?)[-] LINQ to ...

  4. 根据输出设置select的被选中值

    $("#startupStatus").find("option").map(function(i) { if ($('#st-status').val() = ...

  5. Linux常用指令(待补充)

    1.cd进入目录 2../shuntdown.sh  停止tomcat 3.ps -ef |grep +进程名  查看进程状态 4.kill +进程名   强杀kill -9 +进程 5./start ...

  6. 搭建单节点Hadoop应用环境

    虚拟机: VirtualBox 5 Server操作系统: Ubuntu Server 14.04.3 LTS 如果对虚拟机空间和性能不做考虑, 且不习惯用Linux命令, 你也可以使用Ubuntu ...

  7. Mysql 如何做双机热备和负载均衡 (方法一)

    MySQL数据库没有增量备份的机制,但它提供了一种主从备份的机制,就是把主数据库的所有的数据同时写到备份数据库中.实现MySQL数据库的热备份. 下面是具体的主从热备份的步骤:假设主服务器A(mast ...

  8. mysql快速翻页查询方法

    SELECT SQL_NO_CACHE *FROM softdb_testWHERE id > (SELECT idFROM softdb_testORDER BY id DESCLIMIT 5 ...

  9. PCRE兼容正则表达式函数

    1.preg_grep()函数 函数语法: array preg_grep ( string pattern, array input ) 函数功能: 使用数组input中的元素一一匹配表达式patt ...

  10. Java NIO read/write file through FileChannel

    referee:  Java NIO FileChannel A java nio FileChannel is an channel that is connected to a file. Usi ...