Java ArrayList як додавати елементи на початку


183

Мені потрібно додати елементи до ArrayListчерги будь-що, але коли я викликаю функцію для додавання елемента, я хочу, щоб він додав елемент на початку масиву (щоб він мав найнижчий індекс), і якщо масив містить 10 елементів, додаючи новий результат видалення найдавнішого елемента (того, який має найвищий показник).

Хтось має якісь пропозиції?


Ви маєте на увазі, як removeі add?
— Пітер Лорі

Що ви використовуєте arraylist stack queue whateverдля додавання до початку масиву, краще уникати, і це здається, що ви повинні використовувати іншу колекцію.
— Пітер Лорі

По-перше, вам слід щось зробити самостійно. Що ви робили досі?
— Єгошин Максим

Відповіді:


301

Listмає метод add(int, E), тож ви можете використовувати:

list.add(0, yourObject);

Після цього можна видалити останній елемент за допомогою:

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

Однак ви можете переосмислити свої вимоги або використати іншу структуру даних, наприклад, як Queue

EDIT

Можливо, подивіться на Apache CircularFifoQueue:

CircularFifoQueue це чергова перша черга з фіксованим розміром, яка замінює її найдавніший елемент, якщо вона заповнена.

Просто ініціалізуйте його з вами максимального розміру:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
Я б не торкався жодної бібліотеки апачів десятифутовим полюсом, тим більше, що існують класи колекцій гуави. Тут може бути хорошим вибором черга для виселення Guava.
— DPM

26

Використання конкретних структур даних

Існують різні структури даних, оптимізовані для додавання елементів у перший індекс. Майте на увазі, що якщо ви перетворите свою колекцію в одну з них, для розмови, ймовірно, знадобиться часова та просторова складністьO(n)

Деке

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 .

Повернення списку

Дуже простим, але неефективним методом є використання зворотного:

 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 index, елемент E) :

Вставляє вказаний елемент у вказане положення цього списку. Зсуває елемент, який зараз знаходиться у цій позиції (якщо такий є), а всі наступні елементи праворуч (додає один до їх індексів).

Після додавання ви зможете перевірити розмір ArrayList і видалити його в кінці.


4

Ви можете поглянути на Деке. він надає вам прямий доступ до першого та останнього пунктів у списку.


1
Я здивований, що ти єдина відповідь, яка говорить про Деке, це, очевидно, найкраще оптимальне рішення.
— Гійом Ф.

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

У мене була подібна проблема, намагаючись додати елемент на початку існуючого масиву, змістити існуючі елементи праворуч і відкинути найстаріший (масив [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

Удачі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.