Java ArrayList วิธีการเพิ่มองค์ประกอบที่จุดเริ่มต้น


183

ฉันต้องการเพิ่มองค์ประกอบลงในArrayListคิว แต่เมื่อฉันเรียกใช้ฟังก์ชันเพื่อเพิ่มองค์ประกอบฉันต้องการให้เพิ่มองค์ประกอบที่จุดเริ่มต้นของอาร์เรย์ (ดังนั้นจึงมีดัชนีต่ำสุด) และถ้าอาร์เรย์มีองค์ประกอบเพิ่ม 10 รายการ ผลลัพธ์ใหม่ในการลบองค์ประกอบที่เก่าที่สุด (อันที่มีดัชนีสูงสุด)

ไม่มีใครมีข้อเสนอแนะใด ๆ ?


คุณหมายถึงชอบremoveและadd?
Peter Lawrey

คุณกำลังใช้อะไรarraylist stack queue whateverเพื่อเพิ่มเข้าไปในจุดเริ่มต้นของอาเรย์นั้นควรหลีกเลี่ยงและดูเหมือนว่าคุณควรจะใช้คอลเล็กชั่นอื่น
Peter Lawrey

ก่อนอื่นคุณควรทำอะไรด้วยตัวเอง คุณทำอะไรไปแล้ว
Yegoshin Maxim

คำตอบ:


301

Listมีวิธีการadd(int, E)ดังนั้นคุณสามารถใช้:

list.add(0, yourObject);

หลังจากนั้นคุณสามารถลบองค์ประกอบสุดท้ายด้วย:

if(list.size() > 10)
    list.remove(list.size() - 1);

อย่างไรก็ตามคุณอาจต้องการทบทวนความต้องการของคุณใหม่หรือใช้โครงสร้างข้อมูลอื่นเช่น a Queue

แก้ไข

อาจจะดูที่ Apache ของCircularFifoQueue:

CircularFifoQueue เป็นคิวเข้าก่อนออกที่มีขนาดคงที่ซึ่งจะแทนที่องค์ประกอบที่เก่าที่สุดหากเต็ม

เพียงเริ่มต้นด้วยขนาดสูงสุดของคุณ:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
ฉันจะไม่แตะห้องสมุดอาปาเช่ที่มีเสายาวสิบฟุต EvictingQueue ของ Guava อาจเป็นตัวเลือกที่ดีที่นี่
DPM

26

ใช้โครงสร้างข้อมูลเฉพาะ

มีโครงสร้างข้อมูลต่าง ๆ ที่ปรับให้เหมาะสมสำหรับการเพิ่มองค์ประกอบที่ดัชนีแรก อย่างไรก็ตามถ้าคุณแปลงคอลเล็กชั่นของคุณเป็นหนึ่งในนั้นการสนทนาอาจจะต้องใช้เวลาและความซับซ้อนของพื้นที่O(n)

deque

JDK รวมถึงDequeโครงสร้างที่มีวิธีการเช่นaddFirst(e)และofferFirst(e)

Deque<String> deque = new LinkedList<>();
deque.add("two");
deque.add("one");
deque.addFirst("three");
//prints "three", "two", "one"

การวิเคราะห์

ความซับซ้อนของพื้นที่และเวลาในการแทรกมีLinkedListค่าคงที่ ( O(1)) ดูBig-O cheatsheet

การย้อนกลับรายการ

วิธีที่ง่าย แต่ไม่มีประสิทธิภาพคือการใช้ reverse:

 Collections.reverse(list);
 list.add(elementForTop);
 Collections.reverse(list);

หากคุณใช้กระแสข้อมูล Java 8 คำตอบนี้อาจสนใจคุณ

การวิเคราะห์

  • ความซับซ้อนของเวลา: O(n)
  • ความซับซ้อนของอวกาศ: O(1)

ดูการใช้งาน JDKสิ่งนี้มีO(n)ความซับซ้อนของเวลาดังนั้นเหมาะสำหรับรายการขนาดเล็กมากเท่านั้น


การย้อนกลับรายการสองครั้ง มันจะเพิ่มระยะเวลารันไทม์ของอัลกอริทึมด้วยระยะขอบขนาดใหญ่เมื่อเทียบกับโซลูชันที่ยอมรับข้างต้นหรือไม่
Samyak Upadhyay

มันเพิ่ม 2n ดังนั้นใช่ แต่ถ้าคุณมีรายการ <50 คุณจะไม่สามารถสร้างมาตรฐานความแตกต่างของเครื่องจักรที่ทันสมัยที่สุด
Patrick Favre

8

คุณสามารถดูที่เพิ่ม (ดัชนี int, องค์ประกอบ E) :

แทรกองค์ประกอบที่ระบุที่ตำแหน่งที่ระบุในรายการนี้ เลื่อนองค์ประกอบในตำแหน่งปัจจุบัน (ถ้ามี) และองค์ประกอบอื่น ๆ ที่ตามมาทางด้านขวา (เพิ่มองค์ประกอบหนึ่งไปยังดัชนีของพวกเขา)

เมื่อคุณเพิ่มคุณสามารถตรวจสอบขนาดของ ArrayList และลบขนาดที่ส่วนท้าย


4

คุณอาจต้องการดู Deque มันช่วยให้คุณเข้าถึงโดยตรงทั้งรายการแรกและรายการสุดท้ายในรายการ


1
ฉันประหลาดใจที่คุณเป็นคำตอบเดียวที่พูดถึง Deque นี่เป็นทางออกที่ดีที่สุด
Guillaume F.

3

Queueสิ่งที่คุณจะอธิบายเป็นสถานการณ์ที่เหมาะสมกับการใช้งาน

เนื่องจากคุณต้องการaddองค์ประกอบใหม่และองค์ประกอบremoveเก่า คุณสามารถเพิ่มในตอนท้ายและลบออกจากจุดเริ่มต้น ที่จะไม่สร้างความแตกต่างมากนัก

คิวมีวิธีการadd(e)และremove()เพิ่มส่วนท้ายขององค์ประกอบใหม่และลบองค์ประกอบเก่าออกจากจุดเริ่มต้นตามลำดับ

Queue<Integer> queue = new LinkedList<Integer>();
queue.add(5);
queue.add(6);
queue.remove();  // Remove 5

ดังนั้นทุกครั้งที่คุณเพิ่มองค์ประกอบลงไปqueueคุณสามารถสำรองข้อมูลด้วยremoveการเรียกใช้เมธอด


อัปเดต : -

และถ้าคุณต้องการแก้ไขขนาดของQueue , จากนั้นคุณสามารถดู: -ApacheCommons#CircularFifoBuffer

จากdocumentation: -

CircularFifoBuffer เป็นบัฟเฟอร์เข้าก่อนออกก่อนโดยมีขนาดคงที่ซึ่งจะแทนที่องค์ประกอบที่เก่าที่สุดหากเต็ม

Buffer queue = new CircularFifoBuffer(2); // Max size

queue.add(5);
queue.add(6);
queue.add(7);  // Automatically removes the first element `5`

อย่างที่คุณเห็นเมื่อถึงขนาดสูงสุดแล้วเพิ่มองค์ประกอบใหม่โดยอัตโนมัติลบองค์ประกอบแรกที่แทรก


1

ฉันคิดว่าการใช้งานควรง่าย แต่เมื่อพิจารณาถึงประสิทธิภาพคุณควรใช้ LinkedList แต่ไม่ใช่ ArrayList เป็นคอนเทนเนอร์ คุณสามารถอ้างถึงรหัสต่อไปนี้:

import java.util.LinkedList;
import java.util.List;

public class DataContainer {

    private List<Integer> list;

    int length = 10;
    public void addDataToArrayList(int data){
        list.add(0, data);
        if(list.size()>10){
            list.remove(length);
        }
    }

    public static void main(String[] args) {
        DataContainer comp = new DataContainer();
        comp.list = new LinkedList<Integer>();

        int cycleCount = 100000000;

        for(int i = 0; i < cycleCount; i ++){
            comp.addDataToArrayList(i);
        }
    }
}


0

คุณสามารถใช้รหัสนี้

private List myList = new ArrayList();
private void addItemToList(Object obj){
    if(myList.size()<10){
      myList.add(0,obj);
    }else{
      myList.add(0,obj);
      myList.remove(10);
    }
}

0

คุณสามารถใช้วิธีการรายการลบและเพิ่ม

list.add(lowestIndex, element);
list.remove(highestIndex, element);

0

นำตัวอย่างนี้: -

List<String> element1 = new ArrayList<>();
element1.add("two");
element1.add("three");
List<String> element2 = new ArrayList<>();
element2.add("one");
element2.addAll(element1);

-1

คุณสามารถใช้ได้

public List<E> addToListStart(List<E> list, E obj){
list.add(0,obj);
return (List<E>)list;

}

เปลี่ยน E ด้วยประเภทข้อมูลของคุณ

หากจำเป็นต้องลบองค์ประกอบที่เก่าที่สุดคุณสามารถเพิ่ม:

list.remove(list.size()-1); 

ก่อนที่จะกลับคำสั่ง มิฉะนั้นรายการจะเพิ่มวัตถุของคุณที่จุดเริ่มต้นและยังคงองค์ประกอบที่เก่าแก่ที่สุด

นี่จะเป็นการลบองค์ประกอบสุดท้ายในรายการ


-1
import java.util.*:
public class Logic {
  List<String> list = new ArrayList<String>();
  public static void main(String...args) {
  Scanner input = new Scanner(System.in);
    Logic obj = new Logic();
      for (int i=0;i<=20;i++) {
        String string = input.nextLine();
        obj.myLogic(string);
        obj.printList();
      }
 }
 public void myLogic(String strObj) {
   if (this.list.size()>=10) {
      this.list.remove(this.list.size()-1);
   } else {
     list.add(strObj); 
   }
 }
 public void printList() {
 System.out.print(this.list);
 }
}

-2

ฉันมีปัญหาที่คล้ายกันพยายามเพิ่มองค์ประกอบที่จุดเริ่มต้นของอาร์เรย์ที่มีอยู่เลื่อนองค์ประกอบที่มีอยู่ไปทางขวาและละทิ้งองค์ประกอบที่เก่าที่สุด (array [length-1]) วิธีแก้ปัญหาของฉันอาจไม่ได้มีประสิทธิภาพมากนัก แต่ใช้ได้สำหรับวัตถุประสงค์ของฉัน

 Method:

   updateArray (Element to insert)

     - for all the elements of the Array
       - start from the end and replace with the one on the left; 
     - Array [0] <- Element

โชคดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.