Done own realisation of ArrayList#1739
Done own realisation of ArrayList#1739ZarichniyYaroslav wants to merge 4 commits intomate-academy:masterfrom
Conversation
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Your implementation of ArrayList is a good start, but I'm requesting changes because several core requirements have not been met. Please address the following points:
- Array Growth Logic: The array must grow 1.5 times its current capacity (
array.length) when full. Your current logic incorrectly triples the size (size). The growth condition should also besize == array.length. - Use of
System.arraycopy(): The task explicitly requires usingSystem.arraycopy()for moving and copying elements. Your implementation uses manualforloops inadd(T, int),remove(int), and the resizing method. These loops must be replaced. [CHECKLIST ITEM #8] - Prohibited Utility Class: The use of
java.util.Objectsis not allowed by the requirements. Please remove the import and implement a manual null-safe check in theremove(T element)method. [CHECKLIST ITEM #2] - Duplicated Code: The index validation logic is repeated in
set()andremove(int). This should be extracted into a private helper method to adhere to the requirements. [CHECKLIST ITEM #5]
Once these issues are resolved, your solution will be much closer to the requirements. Keep up the effort!
✨ 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
| package core.basesyntax; | ||
|
|
||
| import java.util.NoSuchElementException; | ||
| import java.util.Objects; |
There was a problem hiding this comment.
Using java.util.Objects is not allowed according to checklist item #2. Please remove this import and implement the null-safe equality check in the remove(T element) method manually.
| if (index > size || index < 0) { | ||
| throw new ArrayListIndexOutOfBoundsException("ArrayList index out of bounds"); | ||
| } | ||
| if (size == array.length - 1) { |
There was a problem hiding this comment.
The condition to grow the array should be when it's completely full, i.e., size == array.length. This condition triggers the growth prematurely when there is still one slot available.
| for (int i = size - 1; i >= index; i--) { | ||
| array[i + 1] = array[i]; | ||
| } |
There was a problem hiding this comment.
Checklist item #8 requires using System.arraycopy() to move array elements. This manual loop should be replaced.
| if (index >= size || index < 0) { | ||
| throw new ArrayListIndexOutOfBoundsException("ArrayList index out of bounds"); | ||
| } |
There was a problem hiding this comment.
This index validation logic is repeated in set() and remove(int). Checklist item #5 requires moving repeated logic to a separate private method. A helper method like private void checkIndex(int index) would be a good solution.
| for (int i = index; i < size - 1; i++) { | ||
| array[i] = array[i + 1]; | ||
| } |
There was a problem hiding this comment.
This loop for shifting elements should be replaced by a call to System.arraycopy() to comply with checklist item #8.
| public T remove(T element) { | ||
| return null; | ||
| for (int i = 0; i < size; i++) { | ||
| if (Objects.equals(array[i], element)) { |
There was a problem hiding this comment.
This violates checklist item #2, which prohibits using util classes like Objects. The comparison logic needs to handle null elements without using this helper method.
| } | ||
|
|
||
| private Object[] grow() { | ||
| Object[] growedArray = new Object[size + (size << 1)]; |
There was a problem hiding this comment.
The new array size calculation is incorrect. The requirement is to grow 1.5 times the current capacity. The current logic size + (size << 1) results in 3 times the current size, not 1.5 times the array.length (capacity). The formula should be similar to (int) (array.length * 1.5).
| for (int i = 0; i < this.array.length; i++) { | ||
| growedArray[i] = this.array[i]; | ||
| } |
There was a problem hiding this comment.
Checklist item #8 requires using System.arraycopy() to copy elements from the old array to the new, more capacious one.
…idnt use Objects.equals , used System.arraycopy
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Great job addressing most of the feedback from the previous review! You're very close to completing this task. However, there are a few critical issues with the array growth logic that need to be fixed before this can be approved.
Here are the required changes:
- Incorrect Growth Factor: The
grow()method currently triples the array's capacity (array.length + (array.length << 1)). The requirement is to increase it by 1.5 times. You can achieve this with a right bit shift, for example:oldCapacity + (oldCapacity >> 1). - Incorrect Growth Condition: In the
add(T value, int index)method, the conditionif (size == array.length - 1)causes the array to resize too early. The array should only grow when it's completely full (size == array.length). - Duplicated Code: The
get(int index)method contains an index check that should be replaced with a call to yourindexValidation()helper method to avoid code duplication.
Please address these points, and I'll be happy to review your code again!
✨ 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
| if (index > size || index < 0) { | ||
| throw new ArrayListIndexOutOfBoundsException("ArrayList index out of bounds"); | ||
| } | ||
| if (size == array.length - 1) { |
There was a problem hiding this comment.
The condition to grow the array is incorrect. The array should grow when it is full (size == array.length), but this condition size == array.length - 1 triggers the growth when there is still one empty slot left.
| @Override | ||
| public T get(int index) { | ||
| return null; | ||
| if (index >= size || index < 0) { |
There was a problem hiding this comment.
This violates checklist item #5: 'Don't create repeating code.' You have already created a helper method indexValidation(index) for this exact check. Please reuse it here to avoid code duplication.
| } | ||
|
|
||
| private Object[] grow() { | ||
| Object[] growedArray = new Object[array.length + (array.length << 1)]; |
There was a problem hiding this comment.
The requirement is for the array to grow 1.5 times its current capacity. The current logic, array.length + (array.length << 1), is equivalent to array.length * 3, which triples the capacity.
To achieve 1.5x growth, you could use an expression like array.length + (array.length >> 1), which adds half of the current length to itself.
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Great job on implementing the ArrayList! You've successfully addressed the major feedback from the last review, and your code is functionally correct. I am approving your solution to help you progress, but please take a look at these final suggestions to fully align your code with java.util.ArrayList's behavior:
- Growth Condition: For consistency, it's better to use
size == array.lengthas the condition for resizing in alladdmethods. - Memory Management: In your
removemethods, consider setting the now-unused slot tonullafter shifting elements (e.g.,array[size] = null;). This is a good practice to prevent potential memory leaks. - Readability: The logic for finding an element in
remove(T element)can be made clearer by separating the checks fornulland non-nullelements.
You're doing great work. Keep it up!
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Footnotes
| @Override | ||
| public void add(T value) { | ||
|
|
||
| if (size >= array.length) { |
There was a problem hiding this comment.
While this condition is not incorrect, it's slightly inconsistent with the one in add(T value, int index), which uses size == array.length. To maintain consistency and more accurately represent the condition for resizing (when the array is exactly full), it's better to use size == array.length here as well.
| } | ||
| T removed = (T) array[index]; | ||
| System.arraycopy(array, index + 1, array, index, size - index - 1); | ||
| size--; |
There was a problem hiding this comment.
To fully align with java.util.ArrayList's behavior and prevent potential memory leaks, it's a good practice to set the now-unused slot to null. This allows the garbage collector to reclaim the memory if the removed object is no longer referenced elsewhere.
You can add array[size] = null; after this line.
| public T remove(T element) { | ||
| return null; | ||
| for (int i = 0; i < size; i++) { | ||
| if (array[i] == element || (array[i] != null && array[i].equals(element))) { |
There was a problem hiding this comment.
This logic for finding the element is correct, but it's a bit complex to read at a glance. To improve clarity and align more closely with java.util.ArrayList's implementation, consider separating the logic for null and non-null elements.
A common and more readable approach is:
if (element == null) {
for (int i = 0; i < size; i++) {
if (array[i] == null) {
return remove(i);
}
}
} else {
for (int i = 0; i < size; i++) {
if (element.equals(array[i])) {
return remove(i);
}
}
}| private static final int NEW_ARRAY_LIST_SIZE = 0; | ||
| private Object[] array; | ||
| private int size; | ||
|
|
||
| public ArrayList() { | ||
| array = new Object[NEW_ARRAY_SIZE]; | ||
| size = NEW_ARRAY_LIST_SIZE; | ||
| } |
There was a problem hiding this comment.
int type = 0 by default
| private static final int NEW_ARRAY_LIST_SIZE = 0; | |
| private Object[] array; | |
| private int size; | |
| public ArrayList() { | |
| array = new Object[NEW_ARRAY_SIZE]; | |
| size = NEW_ARRAY_LIST_SIZE; | |
| } | |
| private Object[] array; | |
| private int size; | |
| public ArrayList() { | |
| array = new Object[NEW_ARRAY_SIZE]; | |
| } |
| public T get(int index) { | ||
| return null; | ||
| if (indexValidation(index)) { | ||
| throw new ArrayListIndexOutOfBoundsException("ArrayList index out of bounds"); |
There was a problem hiding this comment.
replace throwing exception to indexValidation method
| return growedArray; | ||
| } | ||
|
|
||
| private boolean indexValidation(int index) { |
There was a problem hiding this comment.
| private boolean indexValidation(int index) { | |
| private void indexValidation(int index) { |
| public T remove(T element) { | ||
| return null; | ||
| for (int i = 0; i < size; i++) { | ||
| if (array[i] == element || (array[i] != null && array[i].equals(element))) { |
There was a problem hiding this comment.
| if (array[i] == element || (array[i] != null && array[i].equals(element))) { | |
| if (array[i] == element || array[i] != null && array[i].equals(element)) { |
No description provided.