集合之链表

数组和数组列表都有一个很大的缺陷---从数组的中间位置删除一个元素要很大的代价:数组中处于被删除元素之后的所有元素都要向数组的前端移动,在数组中插入一个元素也是如此。

链表可以完美解决这个问题。数组在连续的存储位置上存放对象引用,但链表将每个对象存放在独立的结点中,每个结点还存放着序列中下个结点的引用,Java中所有链表都是双向连接-即每个结点还存放着指向前驱结点的引用。

链表是一个有序集合,每个对象位置很重要,LinkedList.add方法将对象添加到链表的尾部。但是在程序中常需要将元素添加到链表的中间。迭代器就是描述集合中位置的,所以依赖于位置的add方法由迭代器负责

迭代器的add方法如果多次调用,将按照提供的次序把元素添加到链表中,被依次添加到迭代器当前位置之前。

当用一个刚刚由Iterator方法返回,并且指向链表表头的迭代器调用add操作时,新添加的元素将变成链表的新表头,当迭代器越过链表的最后一个元素时(hasNext返回false),添加的元素将变成链表的新表尾。

迭代器的set方法用一个新的元素取代调用next或previous返回的上一个元素。

ListIterator<String>iter=list.listIterator();
String oldValue=iter.next();
iter.set(newValue);

可以使用ListIterator类从前后两个方向遍历链表中的元素,并可以添加删除元素

链表不支持快速地随机访问,如果要查看链表的第n个元素,就必须从头开始,越过n-1个元素。

LinkedList类提供了一个用来访问某个特定元素的get方法:--效率并不高

get方法优化:如果索引大于1/2size()将从列表的尾部开始搜索元素

LinkedList<> list=new LinkedList<>();
String obj=list.get(n);

效率及其低的随机访问方法:每次查找一个元素都要从列表的头部重新开始搜索。

for(int i=0;i<list.size();i++){
do something with list.get(i)
}

链表迭代器有一个方法可以告之当前位置的索引。

Java迭代器返回俩个元素之间的位置,所以可以同时产生俩个索引:

nextIndex返回下一次调用next方法时返回元素的整数索引;

previousIndex方法返回下一次调用此方法时返回元素的整数索引这个索引的值比nextIndex方法返回的索引值小1;这两个方法效率非常高。

建议避免使用以整数索引表示链表中位值的所有方法。如果需要对集合进行随机访问,就使用数组或ArrayList,而不使用链表

下面的程序创建了俩个链表,将两个链表合并,然后从第二个链表中每间隔一个元素删除一个元素

当用一个刚刚由Iterator方法返回,并且指向链表表头的迭代器调用add操作时,新添加的元素将变成链表的新表头,当迭代器越过链表的最后一个元素时(hasNext返回false),添加的元素将变成链表的新表尾。

迭代器的remove操作将删除调用next之后迭代器左侧的元素

合并过程:

|ACE                |BDFG

A|CE                |BDFG 

AB|CE              B|DFG

ABCD|E           BD|FG

ABCDEF|         BDF|G

ABCDEFG|

删除过程:

|BDFG     第一次while

B|DFG   --第一个next()

BD|FG   --第二个next()

B|FG     --remove操作

B|FG      第二次while

BF|G      --第一个next()

BFG|      --第二个next()

BF|         remove操作

package com.sust.advanced;

import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class LinkedList {
    public static void main(String[] args) {
        List<String> a=new java.util.LinkedList<>();
        a.add("A");
        a.add("C");
        a.add("E");
        List<String> b=new java.util.LinkedList<>();
        b.add("B");
        b.add("D");
        b.add("F");
        b.add("G");

        ListIterator<String> aIter=a.listIterator();//LinkedList类的listIterator方法返回一个实现了ListIterator接口的迭代器对象
        Iterator<String> bIter=b.iterator();
        while(bIter.hasNext()){     //将集合b的元素插入到集合a中     实现合并
            if(aIter.hasNext())aIter.next();
            aIter.add(bIter.next());
        }
        System.out.println(a);
        bIter=b.iterator();
        while(bIter.hasNext()){
            bIter.next();
            if(bIter.hasNext()){
                bIter.next();
                bIter.remove();
            }
        }
        System.out.println(b);
        a.removeAll(b);
        System.out.println(a);
    }
}

运行结果:



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值