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.