Conversation
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
I am requesting changes because several core requirements and checklist rules are still violated, which will break expected List behavior and likely cause tests to fail. The ArrayList class still has incorrect or incomplete methods: isEmpty() always returns false instead of size == 0, and remove(T value) must throw a NoSuchElementException with a clear message when the element is not found, not silently return null. There are also explicit checklist violations: you import and use java.util.Arrays (e.g., in growIfFull()) and java.util.Objects (even if unused), whereas the task forbids using Objects, Arrays, or other util helpers; instead, allocate a new Object[] with newCapacity = oldCapacity + oldCapacity / 2 and copy using System.arraycopy(...). Index validation logic is duplicated in get, set, and remove(int); per the checklist, extract a single private helper (for example checkIndexForGetSetRemove(int index)) and reuse it in all these methods to avoid repetition and keep behavior consistent. Your custom ArrayListIndexOutOfBoundsException currently ignores the passed message and always uses a hard-coded one; update its constructor to call super(message) (or build a detailed message including index and size) and ensure every thrown exception has an informative message, including the NullPointerException in addAll(...). As a minor but required style fix, remove redundant blank lines at the start of class/method bodies and simplify the add(T value) logic so it first checks if (size == elementData.length) then grows, then adds, without unnecessary else if. Once these functional and checklist-related issues are addressed, your implementation will be much closer to behaving like java.util.ArrayList, and you’re very close—fixing these points will solidify your solution.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
| @@ -1,24 +1,67 @@ | |||
| package core.basesyntax; | |||
|
|
|||
| import java.util.Arrays; | |||
There was a problem hiding this comment.
This line imports java.util.Arrays. This violates the checklist item: "Don't use Objects, Arrays, or any other util class." Remove this import and avoid using Arrays.copyOf.
| package core.basesyntax; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.Objects; |
There was a problem hiding this comment.
This line imports java.util.Objects. This violates the checklist item: "Don't use Objects, Arrays, or any other util class." Remove this import (it's unused).
| private Object[] elementData; | ||
| private int size; | ||
|
|
||
| public ArrayList () { |
There was a problem hiding this comment.
The constructor begins after a blank line. This violates: "Don't begin class or method implementation with an empty line. Remove all redundant empty lines, be careful :)" — remove redundant empty lines before the constructor.
| } | ||
|
|
||
| @Override | ||
| public void add(T value) { |
There was a problem hiding this comment.
The add method uses an if / else if where a simpler check would suffice (check if size == elementData.length then grow, then add). This violates: "Don't complicate if-else construction." Simplify to one conditional.
| if (index < 0 || index > size) { | ||
| throw new ArrayListIndexOutOfBoundsException("The index passed to any of the methods " + | ||
| "is invalid."); |
There was a problem hiding this comment.
Index validation is performed inline here. The checklist requires: "Don't create repeating code. If the logic of your code repeats - move it to a separate private method. For example, the index checks for the get(), set(), and remove() methods should be moved to a separate method." Extract a reusable index-validation helper and call it from all methods that require index checks.
| @Override | ||
| public void addAll(List<T> list) { | ||
|
|
||
| if (list == null) { throw new NullPointerException(); } |
There was a problem hiding this comment.
addAll throws new NullPointerException() without a descriptive message. This violates: "Make your exceptions informative. If you throw an Exception, you should always add an informative message so that it would be clear from the stack trace what exactly went wrong." Add a clear message.
| if (index < 0 || index >= size) { | ||
| throw new ArrayListIndexOutOfBoundsException("The index passed to any of the methods " + | ||
| "is invalid."); |
There was a problem hiding this comment.
Index validation here is duplicated inline. Extract and reuse a single index-validation helper as required by: "Don't create repeating code.... index checks for the get(), set(), and remove() methods should be moved to a separate method."
| } | ||
|
|
||
| @Override | ||
| public boolean isEmpty() { |
There was a problem hiding this comment.
isEmpty() currently returns false unconditionally. It should return size == 0 to behave like java.util.ArrayList. Implement this accordingly.
| private void growIfFull() { | ||
| this.elementData = Arrays.copyOf(this.elementData, this.elementData.length | ||
| + (this.elementData.length >> 1)); | ||
| } |
There was a problem hiding this comment.
The growIfFull() method uses Arrays.copyOf(...), which violates: "Don't use Objects, Arrays, or any other util class." and also violates: "Use System.arraycopy() to move your array elements." Replace this with a manual resize: compute new capacity = old + old/2, allocate a new Object[], and use System.arraycopy(elementData, 0, newArray, 0, size) before assigning elementData = newArray. Also ensure the growth factor is 1.5x as required.
| public class ArrayListIndexOutOfBoundsException extends RuntimeException { | ||
| public ArrayListIndexOutOfBoundsException(String message) { | ||
| super(message); | ||
| super("The index passed to any of the methods is invalid."); |
There was a problem hiding this comment.
The constructor ignores the provided message parameter and always passes a hard-coded string to super(...). This violates the checklist: "Make your exceptions informative. If you throw an Exception, you should always add an informative message so that it would be clear from the stack trace what exactly went wrong." Change to super(message) or build a descriptive message that includes context (e.g., invalid index and size).
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
I am requesting changes because several checklist and task requirements are currently violated, which will block this solution from being accepted. The ArrayList implementation still uses java.util.Arrays.copyOf(...) in growIfFull(), but the checklist explicitly forbids using Arrays and requires manual resizing with new Object[newCapacity] plus System.arraycopy(...) and a 1.5× growth factor. Index validation logic is duplicated across get, set, and remove(int), while the checklist requires extracting this repeated logic into a single private helper method and reusing it for consistency and maintainability. Some exceptions are not informative: addAll(List<T> list) throws new NullPointerException() with no message, and remove(T element) throws new NoSuchElementException() without a message, even though the checklist requires clear, descriptive messages for all thrown exceptions. Additionally, your custom ArrayListIndexOutOfBoundsException constructor currently ignores the message; it must call super(message) so that context like index and size is preserved when you throw it. Finally, the add(T value) method uses an unnecessary if/else branching instead of the simpler pattern if (size == elementData.length) { growIfFull(); } elementData[size++] = value;, which the checklist points out as the preferred, non-complicated structure. Once you replace Arrays.copyOf, centralize index checks, make all exception messages informative, fix the custom exception constructor, and simplify add(T), your solution will align well with the task requirements and checklist.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
| @@ -1,48 +1,127 @@ | |||
| package core.basesyntax; | |||
|
|
|||
| import java.util.Arrays; | |||
There was a problem hiding this comment.
This file imports and later uses Arrays. The checklist explicitly says: "Don't use Objects, Arrays, or any other util class." Replace Arrays.copyOf(...) with explicit allocation of a new Object[] and copy elements using System.arraycopy(...) (new capacity = oldCapacity + oldCapacity / 2). See checklist for the exact restriction.
| private void growIfFull() { | ||
| this.elementData = Arrays.copyOf(this.elementData, this.elementData.length | ||
| + (this.elementData.length >> 1)); |
There was a problem hiding this comment.
The growIfFull() method uses Arrays.copyOf(...), which violates "Don't use Objects, Arrays, or any other util class." and also does not show explicit 1.5× growth logic. The task requires the internal array to grow 1.5 times when full: "the internal array should grow 1.5 times when it is full." Implement int newCapacity = oldCapacity + oldCapacity / 2; Object[] newData = new Object[newCapacity]; System.arraycopy(elementData, 0, newData, 0, size); elementData = newData;.
| public void add(T value) { | ||
|
|
||
| if (elementData.length > size) { | ||
| elementData[size++] = value; | ||
| } else if (elementData.length == size) { | ||
| growIfFull(); | ||
| elementData[size] = value; | ||
| this.size++; | ||
| } |
There was a problem hiding this comment.
The add(T value) method uses an unnecessary if/else branch. This violates checklist: "Don't complicate if-else construction." Simplify to: if (size == elementData.length) { growIfFull(); } elementData[size++] = value; — clearer and avoids duplicate logic.
| public T get(int index) { | ||
| return null; | ||
| if (index < 0 || index >= size) { | ||
| throw new ArrayListIndexOutOfBoundsException("The index passed to the get method " | ||
| + "is invalid."); | ||
| } | ||
| return (T) this.elementData[index]; | ||
| } | ||
|
|
||
| @Override | ||
| public void set(T value, int index) { | ||
| if (index < 0 || index >= size) { | ||
| throw new ArrayListIndexOutOfBoundsException("The index passed to the set method " | ||
| + "is invalid."); | ||
| } | ||
|
|
||
| elementData[index] = value; | ||
| } | ||
|
|
||
| @Override | ||
| public T remove(int index) { | ||
| return null; | ||
| if (index < 0 || index >= size) { | ||
| throw new ArrayListIndexOutOfBoundsException("The index passed to the remove method " | ||
| + "is invalid."); |
There was a problem hiding this comment.
Index validation logic is duplicated in get, set, and remove(int). The checklist requires: "If the logic of your code repeats - move it to a separate private method. For example, the index checks for the get(), set(), and remove() methods should be moved to a separate method." Extract a helper (e.g., checkIndex(int index)) and reuse it to keep behavior consistent and avoid repetition.
| if (list == null) { | ||
| throw new NullPointerException(); |
There was a problem hiding this comment.
In addAll(List<T> list) you throw new NullPointerException() without a message. The checklist requires informative exceptions: "Make your exceptions informative. If you throw an Exception, you should always add an informative message so that it would be clear from the stack trace what exactly went wrong." Add a clear message like "list must not be null".
| return element; | ||
| } | ||
| } | ||
| throw new NoSuchElementException(); |
There was a problem hiding this comment.
When an element is not found remove(T element) throws new NoSuchElementException() with no message. Per checklist: "Make your exceptions informative..." include an informative message (for example: "Element not found: " + element) so failures are easier to understand.
| if (index < 0 || index > size) { | ||
| throw new ArrayListIndexOutOfBoundsException("The index passed to the any of add " | ||
| + "method is invalid."); |
There was a problem hiding this comment.
You throw ArrayListIndexOutOfBoundsException with custom messages in several places. Ensure your custom exception's constructor forwards the message to RuntimeException (i.e., super(message)) so these messages are preserved. The current custom exception implementation (separate file) ignores the input message — that must be fixed. (Fix the exception constructor to public ArrayListIndexOutOfBoundsException(String message) { super(message); }.)
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Your solution is approved as an educational override so you can keep progressing while you refine your style and checklist habits. Functionally, your ArrayList implementation looks solid: you use a default capacity, grow the internal array by 1.5× with System.arraycopy, centralize index checks in checkIndex(), and throw informative custom and standard exceptions as required. The main remaining issue is purely stylistic: several methods (including the constructor, add(T value), addAll(List<T> list), and growIfFull()) start after an extra blank line, which violates the style rule about not beginning class or method bodies with an empty line [CHECKLIST ITEM #6].
To fix this, simply remove the empty line immediately before each of those method bodies and scan the entire ArrayList.java file for any other similar leading blank lines. This might seem minor, but consistently following these formatting rules will help you on larger projects and automated style checks. Overall, you’ve done a good job meeting the core technical requirements—now just tighten up the formatting and you’ll have a very clean solution.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Footnotes
| private static final int DEFAULT_CAPACITY = 10; | ||
| private Object[] elementData; | ||
| private int size; | ||
|
|
There was a problem hiding this comment.
This violates checklist item #6: "Don't begin class or method implementation with an empty line. Remove all redundant empty lines, be careful :)" — remove the blank line immediately before the constructor so the constructor does not start with an empty line. See checklist for the rule .
| this.elementData = new Object[DEFAULT_CAPACITY]; | ||
| this.size = 0; | ||
| } | ||
|
|
There was a problem hiding this comment.
This violates checklist item #6: "Don't begin class or method implementation with an empty line. Remove all redundant empty lines, be careful :)" — remove the blank line immediately before the add(T value) method so the method does not start with an empty line. See checklist for the rule .
| elementData[index] = value; | ||
| this.size++; | ||
| } | ||
|
|
There was a problem hiding this comment.
This violates checklist item #6: "Don't begin class or method implementation with an empty line. Remove all redundant empty lines, be careful :)" — remove the blank line immediately before the addAll(List<T> list) method (and scan the rest of the file for similar redundant empty lines). See checklist for the rule .
| return false; | ||
| return size == 0; | ||
| } | ||
|
|
There was a problem hiding this comment.
This violates checklist item #6: "Don't begin class or method implementation with an empty line. Remove all redundant empty lines, be careful :)" — remove the blank line immediately before the growIfFull() method so the method does not start with an empty line. See checklist for the rule .
No description provided.