ArrayList和LinkedList

发布时间:2024年01月11日

(1)LinkedList

LinkedList底层结构实现和ArrayList底层数据结构实现有着本质上的区别 ArrayList底层实现主要依赖数组,而LinkedList底层实现则是依赖链表。

/**

  • LinkedList的实现是双向链表,因此需要定义首节点和尾结点。

  • 并且需要保存链表中元素的个数。此外,还需要提供无参构造方法,

  • 在构造方法内初始化一个空链表。 */ public class MyLinkedList { private Node first; private Node last; private int size;

    /**

在尾部添加节点

@param o

@return */

public boolean add(Object o){

????????if(size == 0){

????????????????Node newNode = new Node(null,o,null);

????????????????first = newNode; last = newNode;

????????}else{

????????????????//实例化新节点

????????????????Node newNode = new Node(last,o,null);

????????????????last.next = newNode; last = newNode;

????????} size++;

????????return true;

}

/**
 * 在指定索引处添加节点
 * @param index
 * @param o
 * @return
 */
public boolean add(int index,Object o){
 ?  if(index<0 || index>size){
 ? ? ?  throw new IndexOutOfBoundsException("越界!");
 ?  }
 ?  if(index == 0){
 ? ? ?  //获取指定索引处的节点
 ? ? ?  Node newNode = getNode(index);
 ? ? ?  //获取首节点的前置节点
 ? ? ?  Node pre = first.pre;
 ? ? ?  //首节点的前置节点指向新节点
 ? ? ?  pre.next = newNode;
 ? ? ?  //将新节点作为首节点
 ? ? ?  first = newNode;
 ? ? ?  size++;
 ?  }
 ?  if(index == size){
 ? ? ?  //直接将对象添加到尾部
 ? ? ?  add(o);
 ?  }
 ?  //获取索引的节点
 ?  Node indexNode = getNode(index);
 ?  //获取索引节点的前置节点
 ?  Node preNode = indexNode.pre;
 ?  //实例化新节点 per指向索引节点的前置节点,next指向索引节点的后置节点
 ?  Node newNode = new Node(preNode,o,indexNode);
 ?  //索引节点前置节点的next指向新节点
 ?  preNode.next = newNode;
 ?  //索引节点的pre指向新节点
 ?  indexNode.pre = newNode;
 ?  size++;
 ?  return true;
}
?
/**
 * 删除对应索引处的节点
 * @param index
 * @return
 */
public Object remove(int index){
 ?  if(index<0 || index>=size){
 ? ? ?  throw new IndexOutOfBoundsException("越界");
 ?  }
 ?  //初始化返回的值
 ?  Object o = null;
 ?  //删除首节点
 ?  if(index ==0) {
 ? ? ?  //获取首节点的节点值
 ? ? ?  o = first.date;
 ? ? ?  //获取首节点的后置节点
 ? ? ?  Node node = first.next;
 ? ? ?  //首节点的next为null
 ? ? ?  first.next = null;
 ? ? ?  //将首节点的后置节点作为首节点
 ? ? ?  first = node;
 ?  }
 ?  //删除尾节点
 ?  else if(index == size-1){
 ? ? ?  o = last.date;
 ? ? ?  //获取尾节点的前置节点
 ? ? ?  Node perNode = last.pre;
 ? ? ?  //尾节点的前置节点的next置为null
 ? ? ?  perNode.next = null;
 ? ? ?  //将索引节点的尾节点作为尾节点
 ? ? ?  last = perNode;
 ?  }else{
 ? ? ?  //删除中间节点
 ? ? ?  //获取索引处节点
 ? ? ?  Node indexNode = getNode(index);
 ? ? ?  o = indexNode.date;
 ? ? ?  //获取索引节点的前置节点
 ? ? ?  Node preNode = indexNode.pre;
 ? ? ?  //获取索引节点的后置节点
 ? ? ?  Node nextNode = indexNode.next;
 ? ? ?  //将索引节点的前置节点指向索引节点的后置节点
 ? ? ?  preNode.next = nextNode;
 ? ? ?  //将索引节点的后置节点指向索引节点的前置节点
 ? ? ?  nextNode.pre = preNode;
 ? ? ?  //将索引节点的pre置为null
 ? ? ?  indexNode.pre = null;
 ? ? ?  //将索引节点的next置为null
 ? ? ?  indexNode.next = null;
 ?  }
 ?  size--;
 ?  return o;
}
?
/**
 * 修改索引处节点的元素值
 * @param index
 * @param o
 * @return
 */
public Object set(int index,Object o){
 ?  if(index<0||index>=size){
 ? ? ?  throw new IndexOutOfBoundsException("越界!");
 ?  }
 ?  //获取对应索引处的节点
 ?  Node indexNode = getNode(index);
 ?  //获取要删除节点的值
 ?  Object oldValue = indexNode.date;
 ?  //将要修改的值赋值给目标节点
 ?  indexNode.date = o;
 ?  return oldValue;
}
?
/**
 * 获取双向链表的容量
 * @return
 */
public int size(){
 ?  return size;
}
?
/**
 * 获取对应索引处节点的元素值
 * @param index
 * @return
 */
public Object get(int index){
 ?  return getNode(index).date;
}
?
/**
 * 获取对应索引处的Node对象
 * @param index
 * @return
 */
public Node getNode(int index){
 ?  if(index<0 || index>=size){
 ? ? ?  throw new  IndexOutOfBoundsException("越界");
 ?  }
 ?  //获取首节点
 ?  Node current = first;
 ?  for (int i = 0; i < index&&current!=null; i++) {
 ? ? ?  //获取下一个节点
 ? ? ?  current = current.next;
 ?  }
 ?  return current;
}
?
/**
 * 定义链表数据节点
 */
private class Node{
 ?  private Node pre;
 ?  private Object date;
 ?  private Node next;
?
 ?  public Node(Node pre,Object o,Node next){
 ? ? ?  this.pre = pre;
 ? ? ?  this.date = o;
 ? ? ?  this.next = next;
 ?  }
}

}

/**

  • 测试类 */ public class Test { public static void main(String[] args) { MyLinkedList list = new MyLinkedList(); list.add("111"); list.add("222"); list.add("333"); list.add("444"); list.set(1,"777"); list.set(2,"888"); list.remove(0); list.remove(1); System.out.println("-------------"); for (int i = 0; i <list.size(); i++) { System.out.println(list.get(i)); } } }

(2) ArrayList和LinkedList的区别

    1、ArrayList和LinkedList都实现了List接口
    2、ArrayList和LinkedList都是非线程安全的,因此在多线程环境下可能会出现出现不同步的情况
    3、ArrayList底层实现是数组,LinkedList底层实现是双向链表
    4、ArrayList因为底层实现是数组,并且支持随机访问因此查找效率高,但是ArrayList在新增元素时会扩容以及复制数组元素,并且删除时也会进行数组复制,所以增删效率低。而LinkedList不支持随机访问,获取元素时必须从首节点开始从前往后遍历查找,因此查找效率低。但是增加和删除时最多涉及到两个节点的操作,因此增删效率高。

(3) Queue

    Queue 队列通常是指"先进先出"(FIFO)的容器。队列的头部保存在队列中存放时间最长的元素,队列的尾部保存在队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。
    
    boolean add(Object e)∶将指定元素加入此队列的尾部。
    Object element()∶获取队列头部的元素,但是不删除该元素。
    boolean offer(Object e)∶将指定元素加入此队列的尾部。当使用有容量限制的队列时,此方法通常比 add(Object e)方法更好。
    Object peek()∶获取队列头部的元素,但是不删除该元素。如果此队列为空,则返回 null。
    Object poll()∶获取队列头部的元素,并删除该元素。如果此队列为空,则返回 null。
    Object remove()∶获取队列头部的元素,并删除该元素。

public class QueueDemo {

????????public static void main(String[] args) {

????????????????Queue<String> queue= new LinkedList<>();

????????????????//添加元素

????????????????queue.offer("111");

????????????????queue.offer("222");

????????????????queue.offer("333");

????????????????queue.offer("444");

????????????????//添加失败时会抛出异常

????????????????queue.add("555");

????????????????//删除失败时会抛出异常

????????????????queue.remove("555");

????????????????for(String q:queue){

????????????????????????System.out.println(q);

????????????????}

????????????????System.out.println("-----------");

????????????????//返回第一个元素,并在列表中删除

????????????????queue.poll();

????????????????for(String q:queue){

????????????????????????System.out.println(q);

????????????????}

????????????????System.out.println("-----------");

????????????????//返回第一个元素

????????????????System.out.println(queue.element());

????????????????System.out.println("-----------");

????????????????//返回第一个元素

????????????????System.out.println(queue.peek());

? ? ? ? ? ? ? ? System.out.println("-----------");

????????????}

}

文章来源:https://blog.csdn.net/weixin_45804384/article/details/135396814
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。