Skip to content
Open

f #1780

Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 72 additions & 7 deletions src/main/java/core/basesyntax/ArrayList.java
Original file line number Diff line number Diff line change
@@ -1,48 +1,113 @@
package core.basesyntax;

import java.util.Arrays;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import (java.util.Arrays) violates the checklist: "Don't use Objects, Arrays, or any other util class." Remove this import and avoid using Arrays.* methods (use manual logic + System.arraycopy where required).

import java.util.NoSuchElementException;
import java.util.Objects;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import (java.util.Objects) violates the checklist: "Don't use Objects, Arrays, or any other util class." Do not use Objects.equals(); implement equality checks manually (handle nulls explicitly).


public class ArrayList<T> implements List<T> {
private static final int START_INDEX = 0;
private static final int DEFAULT_CAPACITY = 10;
private int capacity;
private T[] elementData;
private int size;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no resize/grow helper method. The checklist explicitly requires: "Resize the array in a separate method." Add a private method that grows elementData by 1.5x (matching java.util.ArrayList behavior) and use System.arraycopy() to copy elements.

public ArrayList() {
elementData = (T[]) new Object[DEFAULT_CAPACITY];
capacity = DEFAULT_CAPACITY;
}

@Override
public void add(T value) {

if (size >= capacity) {
grow();
}
elementData[size] = value;
size++;
}

@Override
public void add(T value, int index) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method signature here is add(T value, int index), but the task explicitly refers to add(int index, T value) (the indexed-add should follow the required order). Ensure the method signature matches the requirement/interface and the documented API.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indexed add method uses the signature add(T value, int index). This violates the requirement: "The indexed add method must: Use the signature add(int index, T value) (matching the List interface)." Change the method signature to add(int index, T value) so it matches the List interface and expected API.

if (index > size || index < START_INDEX) {
throw new ArrayListIndexOutOfBoundsException("index %s out of bounds for length %s"
.formatted(index, size));
}
Comment on lines +28 to +31
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You perform index validation here manually instead of reusing the index-check helper. The requirements state you should move repeated index checks to a private helper and use it for add(int index, T value) as well. Also keep in mind that adding at index == size is allowed (the checker must allow upper bound == size).

Comment on lines +28 to +31
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block performs its own index validation instead of reusing the shared index-check helper. The requirements state: "Index checking logic that is shared by methods like get(), set(), and remove() must be moved to a separate private method to avoid repeating code" and "The indexed add method must: Use a shared index-check helper method instead of its own index validation." Refactor so the indexed add calls a common helper (or a helper variant) that allows index == size for insertion at the end.

if (size >= capacity) {
grow();
}
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = value;
size++;

}

@Override
public void addAll(List<T> list) {

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

@Override
public T get(int index) {
return null;
checkIndex(index);
return elementData[index];
}

@Override
public void set(T value, int index) {
checkIndex(index);

elementData[index] = value;
}

@Override
public T remove(int index) {
return null;
checkIndex(index);
T value = elementData[index];
System.arraycopy(elementData, index + 1, elementData, index, size - index - 1);
size--;
Comment on lines +65 to +66
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After shifting elements and decrementing size you must null out the former last element position to avoid memory leaks and ensure toString()/iteration don't see stale data. The requirements say: "When an element is removed, shift size - index - 1 elements to close the gap using System.arraycopy. Decrement size. Set the former last element position to null." Add elementData[size] = null; after size--.

return value;
}

@Override
public T remove(T element) {
return null;
int index = 0;
for (T elementDatum : elementData) {
if (Objects.equals(elementDatum, element)) {
T value = elementData[index];
System.arraycopy(elementData, index + 1, elementData, index, size - index);
size--;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop iterates over the whole backing array (elementData) including unused slots and uses Objects.equals. Per checklist you must not use Objects and you should iterate only up to size. Also the subsequent System.arraycopy call uses the wrong length: size - index is incorrect for shifting elements after removal — it should be size - index - 1 (same logic as in remove(int index)).

return value;
}
index++;
}
throw new NoSuchElementException();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing NoSuchElementException without an informative message violates the checklist: "Make your exceptions informative." Add a clear message indicating the element was not found (for easier debugging).

}

@Override
public int size() {
return 0;
return size;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size() is implemented correctly returning size, but other methods that rely on it are unimplemented; ensure consistency when you implement add/remove methods.

}

@Override
public boolean isEmpty() {
return false;
return size == 0;
}

@Override
public String toString() {
return Arrays.toString(elementData);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toString() uses Arrays.toString(elementData), which (1) uses a forbidden util class and (2) prints the whole backing array including nulls beyond size. The result should match java.util.ArrayList and represent only the elements up to size. Implement a manual toString that iterates to size and builds the string.

}

private void grow() {
capacity += capacity / 2;
elementData = Arrays.copyOf(elementData, capacity);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The grow() method uses Arrays.copyOf(...), which both uses a forbidden util class and does not follow the requirement to allocate a new array and copy elements with System.arraycopy(). Implement grow by creating a new Object[newCapacity] and copying elementData into it with System.arraycopy().

}

private void checkIndex(int index) {
if (index > size - 1 || index < START_INDEX) {
throw new ArrayListIndexOutOfBoundsException("index %s out of bounds for length %s"
.formatted(index, size));
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no toString() implementation. The checklist requires: "toString() implementation must: Not use Arrays.toString. Iterate only over indices 0 to size - 1. Build the string manually (for example, using StringBuilder) so output matches java.util.ArrayList and does not print unused null entries." Implement toString() accordingly so output matches java.util.ArrayList and doesn't include unused null slots.

22 changes: 22 additions & 0 deletions src/main/java/core/basesyntax/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package core.basesyntax;

public class Main {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The internal storage elementData is declared but never initialized and DEFAULT_SIZE is not used. You need a constructor that initializes elementData = new Object[DEFAULT_SIZE] so the list has the required default capacity (same as java.util.ArrayList).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import violates the checklist: "Don't use Objects, Arrays, or any other util class." You also use Arrays.copyOf and Arrays.toString below; remove this import and avoid java.util.Arrays usage in favor of allocating a new backing array and using System.arraycopy (and building toString using elements up to size).

public static void main(String[] args) {
ArrayList<String> test = new ArrayList<>();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import violates the checklist: "Don't use Objects, Arrays, or any other util class." Replace Objects.equals usage with an explicit null-safe comparison (e.g. (e == null ? element == null : e.equals(element))).

System.out.println(test);
for (int i = 0; i < 5; i++) {
test.add(Integer.toString(i));
}
System.out.println(test);
test.remove("2");
System.out.println(test);

java.util.ArrayList<String> utilTest = new java.util.ArrayList<>();
for (int i = 0; i < 5; i++) {
utilTest.add(Integer.toString(i));
}
System.out.println(utilTest);
utilTest.remove(-2);
System.out.println(utilTest);
}
}
Loading