- 浏览: 62529 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
xuhang1128:
http://www.ihacklog.com/linux/m ...
Linux下安装memcached -
greatghoul:
常用的功能挺全面的。
vim使用技巧两篇
http://www.cnblogs.com/huangfox/archive/2010/10/11/1847863.html
一、 LinkedList 3.1 创建:LinkedList() LinkedList底层的数据结构是一个双向链表。既然是双向链表,那么必定存在一种数据结构——我们可以称之为节点,节点实例保存业务数据,前一个节点的位置信息和后一个节点位置信息,如下图所示: 图——双线链表及节点示意图 首先来了解节点类: private static class Entry<E>{ Eelement; Entry<E> next; Entry<E> previous; Entry(Eelement, Entry<E>next, Entry<E>previous) { this.element = element; this.next = next; this.previous = previous; } } 节点类很简单,element存放业务数据,previous与next分别存放前后节点的信息(在数据结构中我们通常称之为前后节点的指针)。 声明LinkedList对象时,创建一个Entry对象,不过全部为空。 private transient Entry<E> header = new Entry<E>(null, null, null); private transient int size = 0; 在执行构造函数的时候,将header实例的previous和next全部指向header实例。 public LinkedList(){ header.next = header.previous = header; } 执行完构造函数后,header实例自身形成一个闭环,如下图所示: 图——初始化LinkedList 3.2 添加数据:add() 从源代码中我们可知——给LinkedList添加数据是从双向链表的头开始的,代码如下所示: public boolean add(E e) { addBefore(e, header); return true; } private Entry<E> addBefore(Ee, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next =newEntry; newEntry.next.previous =newEntry; size++; modCount++; return newEntry; } 下面分解“添加第一个数据”的步骤: 第一步:初始化后LinkedList实例的情况: 图——初始化后 第二步:初始化一个预添加的Entry实例(newEntry)。 Entry<E> newEntry = newEntry<E>(e, entry, entry.previous); 图——创建新节点实例 第三步:调整新加入节点和头结点(header)的前后指针。 newEntry.previous.next = newEntry; newEntry.previous即header,newEntry.previous.next即header的next指向newEntry实例。在上图中应该是“4号线”指向newEntry。 newEntry.next.previous = newEntry; newEntry.next即header,newEntry.next.previous即header的previous指向newEntry实例。在上图中应该是“3号线”指向newEntry。 调整后如下图所示: 图——加入第一个节点后LinkedList示意图 下面分解“添加第二个数据”的步骤: 第一步:新建节点。 图——添加第二个节点 第二步:调整新节点和头结点的前后指针信息。 图——调整前后指针信息 添加后续数据情况和上述一致,LinkedList实例是没有容量限制的。 3.3 删除数据:remove()、remove(int)、remove(Object) LinkedList的数据删除操作虽然有多种(这里认为只包括remove()、remove(int)、remove(Object) ),但是真正执行删除操作的代码如下所示: private E remove(Entry<E> e) { if (e == header) throw new NoSuchElementException(); E result = e.element; e.previous.next = e.next; e.next.previous = e.previous; e.next = e.previous = null; e.element = null; size--; modCount++; return result; } Remove方法接收的参数是一个节点实例,即预被删除的节点。只不过remove()是删除的第一个节点(头结点后的第一个节点)—— public EremoveFirst() { return remove(header.next); } Remove(int)是删除指定位置的节点—— private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; if(index < (size >> 1)) {//判断是从头开始遍历还是从尾开始遍历 for (int i = 0; i<= index; i++) e = e.next; } else { for (int i = size;i > index; i--) e = e.previous; } return e; } Remove(Object)是删除指定内容的节点—— public boolean remove(Object o) { if (o==null) { for (Entry<E> e = header.next; e != header; e = e.next) { if (e.element==null) { remove(e); return true; } } } else { for (Entry<E> e = header.next; e != header; e = e.next) { if (o.equals(e.element)) { remove(e); return true; } } } return false; } 在回到我们的remove(Entry e)方法: 由于删除了某一节点因此调整相应节点的前后指针信息,如下: e.previous.next = e.next;//预删除节点的前一节点的后指针指向预删除节点的后一个节点。 e.next.previous = e.previous;//预删除节点的后一节点的前指针指向预删除节点的前一个节点。 清空预删除节点: e.next = e.previous = null; e.element = null; 交给gc完成资源回收,删除操作结束。 与ArrayList比较而言,LinkedList的删除动作不需要“移动”很多数据,从而效率更高。 3.4 获取数据:get(int) Get(int)方法的实现在remove(int)中已经涉及过了。首先判断位置信息是否合法(大于等于0,小于当前LinkedList实例的Size),然后遍历到具体位置,获得节点的业务数据(element)并返回。 注意:为了提高效率,需要根据获取的位置判断是从头还是从尾开始遍历。 private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; if(index < (size >> 1)) {//判断是从头开始遍历还是从尾开始遍历 for (int i = 0; i<= index; i++) e = e.next; } else { for (int i = size;i > index; i--) e = e.previous; } return e; } 注意细节:位运算与直接做除法的区别。 3.5 遍历数据:Iterator() 对ArrayList的iterator有所了解后,在此重点关注以下几点: 当调用iterator方法是,每次都创建一个ListItr实例,它拥有一个属性cursor,起到游标的作用。 Iterator实例的hasNext方法: public boolean hasNext() { return cursor != size(); } 当游标跑到最后时返回false,说明遍历完成。 Iterator实例的next方法: public E next() { checkForComodification(); try { Enext = get(cursor); lastRet= cursor++; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw newNoSuchElementException(); } } 通过get方法返回当前游标位置的节点内容,并将游标后移一个位置。 LinkedList在遍历的过程中,如果有添加、删除等动作发生,会导致ConcurrentModificationException异常,和ArrayList类似。 3.6 判断存在或获取位置 获取位置的IndexOf方法在remove(Object)中已经涉及,而判断存在的contains(Object)方法则主要是调用IndexOf方法,根据IndexOf返回的位置和-1进行比较进而判断指定数据是否存在。 3.7 注意 LinkedList是无容量限制的; LinkedList是非线程安全的; LinkedList是基于双向链表实现的,当数据顺序无关的情况下,选择ArrayList还是LinkedList要从各动作的执行效率综合考虑。
发表评论
-
JVM内存分析及导致内存溢出的不健壮代码及解决办法
2011-01-30 14:10 865关键字: Jvm , 内存 ... -
Java集合类--ArrayList
2011-01-30 13:59 780http://www.cnblogs.com/huangf ... -
Java集合类--HashMap
2011-01-30 13:57 665关键字: java , collec ... -
Java运行时绑定探讨
2011-01-30 13:46 578关键字: java , 多态 , 重载 , 重写 , 动 ... -
浅谈equals和hashcode
2011-01-30 13:45 600关键字: equals , hashcode 转 ... -
Junit4参数化测试
2011-01-30 13:45 639关键字: junit , 参数化 转自:http ... -
Java线程安全总结
2011-01-30 13:39 618关键字: java , 线程安全 , synchroni ... -
《软件开发沉思录》之对象健身操
2011-01-30 13:28 703关键字: 编码规范 最近看了一部分《软件开发沉思 ... -
Sun HotSpot JVM内存管理及垃圾收集
2011-01-30 13:21 1080关键字: jvm , 内存管理 , 垃圾收集 ...
相关推荐
Java集合类——List接口 Java中的集合类是用来存放对象的,相当于一个容器,里面包容着一组对象。Java API提供的集合类位于java.util包内。Java中的集合类可以分为两类,一类是数组,另一类是集合。数组也是容器,...
总之,`LinkedList`是Java集合框架中一个重要的列表实现,适用于需要高效执行链式操作的场景。理解其工作原理和特性对于优化Java程序的性能至关重要。在实际编程中,开发者应根据具体需求选择合适的集合类型。
总的来说,理解并熟练运用Java集合框架中的Map接口及其实现,对于JSP应用开发来说至关重要。正确选择和使用这些类可以帮助我们编写出高效、可维护的代码。在实际项目中,应根据具体需求和场景来决定使用哪种集合类型...
本文将深入探讨Java集合类的汇总,包括List、Set和Map这三大核心接口及其实现类。 首先,让我们从List接口开始。List是一种有序的集合,允许有重复元素,并且支持通过索引来访问元素。ArrayList和LinkedList是List...
Java 集合类 List-Set-Map 的区别和联系 Java 集合类 List、Set 和 Map 是 Java 语言中最基本的集合类,它们之间存在着紧密的联系和区别。在本文中,我们将对 Java 集合类 List、Set 和 Map 的区别和联系进行详细的...
理解并熟练运用Java集合体系中的List、Set、Map接口及其实现类,对于日常开发和面试来说至关重要,因为它们是许多Java框架和库的基础。在实际项目中,根据需求选择合适的集合类型可以提高代码的效率和可维护性。在...
### 精通Java集合框架——List, Set, Map #### 概述 Java集合框架是一种高度抽象且灵活的数据组织工具,它通过一系列接口来定义不同类型的数据容器,并提供了丰富的操作这些容器的方法。本文将深入探讨Java集合...
Java 集合类详解 Java 集合类是 Java 语言中的一种基本数据结构,用于存储和操作大量数据。集合类可以分为三大类:Collection、List 和 Set。 Collection 是集合框架中的根接口,提供了基本的集合操作,如 add、...
在Java编程语言中,LinkedList集合类是一个非常重要的数据结构,它可以用来实现栈和队列这两种特殊的数据结构。LinkedList是一个双链表,每个节点包含数据元素和两个引用,分别指向前后节点,这使得在列表中进行插入...
`Collection`接口是Java集合框架的核心接口之一,它是所有集合类的根接口。该接口定义了一组对象的通用操作,并且是`Set`和`List`接口的父接口。 **Collection接口的主要特点**: - 可以存放不同类型的数据。 - 子...
### Java集合排序及Java集合类详解 #### 一、集合框架概述 集合框架是Java编程语言的核心组件之一,用于组织和操作数据集。Java集合框架提供了多种数据结构,包括列表(List)、集(Set)和映射(Map),这些数据结构...
Java集合可以分为两大类:Collection和Map。 Java集合的类型 Java集合有多种类型,常见的有ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。 * ArrayList:是一个基于数组的列表实现,支持随机...
- `java.util`包中的ArrayList, LinkedList, HashMap等是常用的集合类,提供了存储和操作对象的方法。 - 集合框架包括List, Set, Queue, Map等接口,以及它们的实现类。 7. **多线程**: - Java内置对多线程的...
### Java集合类学习笔记知识点详解 #### 一、集合框架概述 ##### 1.1.1 容器简介 在Java编程中,容器是用于存储和管理对象集合的重要工具。当我们处理大量的对象时,比如存储多个员工的信息,仅仅依赖于基本的...
根据给定文件的信息,我们可以总结出以下关于Java集合的相关知识点: ### 一、集合容器概述 #### 1. 什么是集合? 集合(Collection)是指在Java中用来存储、检索及操作一组对象的一种容器。它是一种高级的数据...
### Java集合类性能分析 #### 一、Java集合框架概览 Java集合框架是一个非常重要的概念,它提供了处理数据集合的标准方法。集合框架的核心部分主要包括集合接口、抽象类以及具体的实现类。 - **集合接口**:Java...
### Java集合类详解总结 在Java编程中,集合框架(Collection Framework)是处理一组对象的强大工具,它提供了标准的数据结构来存储和操作这些对象。Java集合框架主要包括`Collection`、`Set`、`List`、`Queue`、`...
ArrayList和LinkedList是Java集合框架中两种重要的动态数组实现,它们都是List接口的实现类,但它们在存储和操作数据方面有着显著的区别。本文件"arraylist-linkedlist-test.zip"主要探讨了在执行添加和删除元素操作...
Java集合类是Java编程语言中用于存储和管理对象的关键组件,它们构成了Java Collections Framework的核心。这个框架提供了一组高效、灵活的数据结构,使得开发者能够轻松地处理数据集合,而无需关心底层实现的复杂性...
Java集合框架提供了多种数据结构供选择,根据实际需求可以选择适当的数据结构。同时,为了保持数据的一致性,可能需要在“一”端添加删除操作时同步更新“多”端的集合。 3. **对象的多对多关系**: 多对多关系...