I'm struggling mightly on doing selection sort on an ArrayList of Strings to alphabetize them. I have no idea what I'm doing wrong. But its just not working properly for me. Heres my code.
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add("d");
list.add("f");
list.add("c");
System.out.println(list);
int i;
int j;
int minValue;
int minIndex;
for (i=0; i<list.size(); i++) {
System.out.println(list.get(i));
char iLetter = (list.get(i).charAt(0));
int iValue = (int) iLetter;
minValue = iValue;
minIndex = i;
for(j=i; j<list.size(); j++) {
char jLetter = list.get(j).charAt(0);
int jValue = (int) jLetter;
if (jValue < minValue) {
minValue = jValue;
minIndex = j;
}
}
if(minValue < iValue) {
int temp = iValue;
char idx = list.get(minIndex).charAt(0);
int idxValue = (int) idx;
iValue = idxValue;
idxValue = temp;
}
}
System.out.println(list);
}
It still prints it out as ["a", "d", "f", "c"]
You are not updating your list anywhere in your loop, so it remains unsorted.
In order to actually swap elements of the list, replace:
if(minValue < iValue) {
int temp = iValue;
char idx = list.get(minIndex).charAt(0);
int idxValue = (int) idx;
iValue = idxValue;
idxValue = temp;
}
with:
if(minValue < iValue) {
Collections.swap (list, i, minIndex);
}
Collections.swap performs the following modification:
list.set(i, list.set(minIndex, list.get(i)));
Now the output will be
[a, c, d, f]
As mentioned, you need to do the actual swapping in the list, not just the temporary variables (doh!).
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("d");
list.add("f");
list.add("c");
System.out.println(list);
for (int i = 0; i < list.size(); i++) {
String smallest = list.get(i);
int smallestIndex = i;
for (int j = i; j < list.size(); j++) {
String value = list.get(j);
if (value.compareTo(smallest) < 0) {
smallest = value;
smallestIndex = j;
}
}
if (smallestIndex != i) {
String head = list.get(i);
list.set(i, smallest);
list.set(smallestIndex, head);
}
}
System.out.println(list);
}
Additionally, your code is just a single method, AKA spaghetti code. To make it more object-oriented you could make the following changes.
import java.util.*;
public class SelectionSort<T extends Comparable> {
private List<T> values;
public SelectionSort(List<T> values) {
this.values = values;
}
private void sort() {
for (int headIndex = 0; headIndex < values.size(); headIndex++) {
sortFrom(headIndex);
}
}
private void sortFrom(int headIndex) {
int smallestIndex = findSmallestFrom(headIndex);
if (smallestIndex != headIndex) {
swap(headIndex, smallestIndex);
}
}
private int findSmallestFrom(int i) {
int smallestIndex = i;
T smallest = values.get(i);
for (int j = i; j < values.size(); j++) {
T value = values.get(j);
if (value.compareTo(smallest) < 0) {
smallest = value;
smallestIndex = j;
}
}
return smallestIndex;
}
private void swap(int i, int j) {
T head = values.get(i);
values.set(i, values.get(j));
values.set(j, head);
}
public static void main(String[] args) {
List<String> values = createTestData();
System.out.println(values);
SelectionSort selectionSort = new SelectionSort<>(values);
selectionSort.sort();
System.out.println(values);
}
private static List<String> createTestData() {
List<String> values = new ArrayList<>();
values.add("a");
values.add("d");
values.add("f");
values.add("c");
return values;
}
}
Some of the changes I made:
Separate method for creation of test data
Separate method for printing the before and after state of the list and calling the sort
Create an instance instead of only static code
separate iterations and logic into meaningful methods
Rename the 'list' variable to 'values'. The fact that it's a list is already clear. The convention is to name a collection by the meaning of the data it contains
Introduced a generic type variable on the class (<T extends Comparable>). This allows any type of data to be sorted, as long as it implements the Comparable interface
Related
I have a school assignment where I need to create a very basic clone of ArrayList in java. It only needs to work with strings and have minimal functionality (size, add, get). This is what I have so far. I realise that there is probably many things that could be improved, but right now I am trying to work on this error
Exception in thread "main" java.lang.NullPointerException
at pt2.ArrayListMine.expand(ArrayListMine.java:13)
at pt2.ArrayListMine.add(ArrayListMine.java:32)
at pt2.Driver.main(Driver.java:21
I think the problem is that when I call expand() instead of moving the strings from array to backup and then backup to array it is passing pointers, so after I call it I effectivly have array pointing to backup pointing to array. Im not shure if/how I could force it to pass the string instead of the pointer so I am hoping I can get some advice. Thanks!
package pt2;
public class ArrayListMine {
private String[] array;
private String[] backup;
private int array_size = 0;
public void ArrayListMine() {
array = new String[10];
}
private void expand() {
if(array_size == array.length) {
for(int l = 0; l < array.length; l++) {
backup[l] = array[l];
}
int new_size = (int) (array.length * 2);
array = new String[new_size];
for(int l = 0; l < backup.length; l++) {
array[l] = backup[l];
}
}
}
public int size() {
return array_size;
}
public void add(String value) {
array_size = array_size + 1;
System.out.println(array_size);
expand();
array[array_size - 1] = value;
}
public String get(int index) {
return array[index];
}
}
array is null. Because this
public void ArrayListMine() {
array = new String[10];
}
is not a constructor. Remove the void. Like,
public ArrayListMine() {
array = new String[10];
}
Next, use backup = Arrays.copyOf(array, array.length) to copy array to backup. Because this
backup[l] = array[l];
will also blow-up.
Initialise the back up with the array size before copying.
backup = new String[array.length]; in side expand method before copying to it.
public class ArrayListMine {
private String[] array;
private String[] backup;
private int array_size = 0;
public ArrayListMine() {
array = new String[10];
}
private void expand() {
if(array_size == array.length) {
backup = new String[array.length];
for(int l = 0; l < array.length; l++) {
backup[l] = array[l];
}
int new_size = (int) (array.length * 2);
array = new String[new_size];
for(int l = 0; l < backup.length; l++) {
array[l] = backup[l];
}
}
}
public int size() {
return array_size;
}
public void add(String value) {
array_size = array_size + 1;
System.out.println(array_size);
expand();
array[array_size - 1] = value;
}
public String get(int index) {
return array[index];
}
public static void main(String[] args) {
ArrayListMine arrayListMine = new ArrayListMine();
for(int i=0;i<=20;i++) {
arrayListMine.add("test "+i);
}
}
}
and further you can replace your for loop with System.arrayCopy
private void expand() {
if(array_size == array.length) {
backup = new String[array.length];
System.arraycopy(array, 0, backup, 0, array_size);
/*for(int l = 0; l < array.length; l++) {
backup[l] = array[l];
}*/
int new_size = (int) (array.length * 2);
array = new String[new_size];
/*for(int l = 0; l < backup.length; l++) {
array[l] = backup[l];
}*/
System.arraycopy(backup, 0, array, 0, array_size);
}
}
So I have some code that uses Merge Sort for an array int and I'm trying to format the code so it works with array Strings instead like having it sort by alphabetical order so ["peas", "zucchini", "apple", "berries"] turns into ["apple", "berries", "peas", "zucchini"]. If anyone could help me that would be great and much appreciated.
Here's my code
import java.util.Arrays;
public class MergeSortDemo
{
public static void main(String[] args)
{
int[] a = ArrayUtil.randomIntArray(20, 100);
System.out.println(Arrays.toString(a));
MergeSorter sorter = new MergeSorter(a);
sorter.sort();
System.out.println(Arrays.toString(a));
}
}
The second part
import java.util.Random;
public class ArrayUtil
{
private static Random generator = new Random();
public static int[] randomIntArray(int length, int n)
{
int[] a = new int[length];
for (int i = 0; i < a.length; i++)
a[i] = generator.nextInt(n);
return a;
}
}
Final part
public class MergeSorter
{
private int[] a;
public MergeSorter(int[] anArray)
{
a = anArray;
}
public void sort()
{
if (a.length <= 1) return;
int[] first = new int[a.length / 2];
int[] second = new int[a.length - first.length];
for (int i = 0; i < first.length; i++) { first[i] = a[i]; }
for (int i = 0; i < second.length; i++)
{
second[i] = a[first.length + i];
}
MergeSorter firstSorter = new MergeSorter(first);
MergeSorter secondSorter = new MergeSorter(second);
firstSorter.sort();
secondSorter.sort();
merge(first, second);
}
private void merge(int[] first, int[] second)
{
int iFirst = 0;
int iSecond = 0;
int j = 0;
while (iFirst < first.length && iSecond < second.length)
{
if (first[iFirst] < second[iSecond])
{
a[j] = first[iFirst];
iFirst++;
}
else
{
a[j] = second[iSecond];
iSecond++;
}
j++;
}
while (iFirst < first.length)
{
a[j] = first[iFirst];
iFirst++; j++;
}
while (iSecond < second.length)
{
a[j] = second[iSecond];
iSecond++; j++;
}
}
}
Pretty much the only thing you have to change is the part in "part three" where you compare the two array-elements to see which one is bigger. Obviously you can't use a binary operator like '<' on a String, but the String class offers a compareTo(String s) method, which returns an int-value that is either positive or negative, depending on whether the compared String is lexicographically higher or lower, or zero if they are equal. For more detail look into the Java API.
Note:
Obviously you need to change the int-Array to a String-Array to, but I think that goes without saying...
first you will remove ArrayUtil class and create and initialize your array in a MergeSortDemo class , and change the type of array into String , Here will be MergeSortDemo class.
import java.util.Arrays;
public class MergeSortDemo
{
public static void main(String[] args) {
// TODO code application logic here
String [] a = {"peas", "zucchini", "apple", "berries"};
System.out.println(Arrays.toString(a));
MergeSorter sorter = new MergeSorter(a);
sorter.sort();
System.out.println(Arrays.toString(a));
}
}
in final part you will change every int array to String array and your condition will be >> ( first[iFirst].compareTo(second[iSecond])<0 ),I see (<0) because compareTo method will return a value less than 0 if one String less than other .Here will be MergeSorter class.
class MergeSorter
{
private String[] a;
public MergeSorter(String[] anArray)
{
a = anArray;
}
public void sort()
{
if (a.length <= 1) return;
String[] first = new String[a.length / 2];
String[] second = new String[a.length - first.length];
for (int i = 0; i < first.length; i++) { first[i] = a[i]; }
for (int i = 0; i < second.length; i++)
{
second[i] = a[first.length + i];
}
MergeSorter firstSorter = new MergeSorter(first);
MergeSorter secondSorter = new MergeSorter(second);
firstSorter.sort();
secondSorter.sort();
merge(first, second);
}
private void merge(String[] first, String[] second)
{
int iFirst = 0;
int iSecond = 0;
int j = 0;
while (iFirst < first.length && iSecond < second.length)
{
if (first[iFirst].compareTo(second[iSecond])<0)
{
a[j] = first[iFirst];
iFirst++;
}
else
{
a[j] = second[iSecond];
iSecond++;
}
j++;
}
while (iFirst < first.length)
{
a[j] = first[iFirst];
iFirst++; j++;
}
while (iSecond < second.length)
{
a[j] = second[iSecond];
iSecond++; j++;
}
}
}
I'm having trouble with a bubbleSort method for my very unique homework assignment.
We are supposed to use a sorting method of our choice to sort, get this, a linked list of int arrays. Not an ArrayList not just a LinkedList. It works like a linked list but the each Node contains an array of a capacity of 10 ints.
I am stuck on the sorting method. I chose bubbleSort just because it was used in the last assignment and I felt most familiar with it. Any tips for a better sorting method to try would be considered helpful as well.
Here is my code:
public void bubbleSort() {
current = head; // Start at the head ArrayNode
for (int i = 0; i < size; i++) { // iterate through each ArrayNode
currentArray = current.getArray(); // get the array in this ArrayNode
int in, out;
for (out = size-1; out > 1; out--) { // outer loop (backwards)
for (in = 0; in < out; in++) { // inner loop (forwards)
if (currentArray[in] > currentArray[in+1]) // out of order?
swap(in, in+1); // swap them!
}
}
current.setArray(currentArray);
current = current.getNext();
}
}// End bubbleSort() method
// A helper method for the bubble sort
private void swap(int one, int two) {
int temp = currentArray[one];
currentArray[one] = currentArray[two];
currentArray[two] = temp;
} // End swap() method
This is a picture example of what I am supposed to be doing.
I have found a solution with selectionsort. There are a few test values, just run it to see it.
I can provide further information if needed.
import java.util.ArrayList;
import java.util.Random;
public class ArrayedListSort {
int listsize = 5; // how many nodes
int maxValue = 99; // the highest value (0 to this)
int nodeSize = 3; // size for every node
public static void main(String[] args) {
// run non static
new ArrayedListSort().runTest();
}
/**
* Log function.
*/
public void log(Object s) {
System.out.println(s);
}
public void logNoBR(Object s) {
System.out.print(s);
}
/**
* Output of list we have.
*/
public void logMyList(ArrayList<ListNode> listNode, String name) {
log("=== LOG OUTPUT " + name + " ===");
for ( int i=0; i < listNode.size(); i++) {
logNoBR(" node <" + i + ">");
logNoBR(" (");
for (int j=0; j < listNode.get(i).getSize(); j++) {
if ( j != (listNode.get(i).getSize()-1)) // if not last add ","
logNoBR( listNode.get(i).getValueAt(j) + "," );
else
logNoBR( listNode.get(i).getValueAt(j) );
}
log(")");
}
log("=====================================\n");
}
public void runTest() {
// create example List
ArrayList<ListNode> myList = new ArrayList<ListNode>();
// fill the nodes with random values
for ( int i = 0; i < listsize; i++) {
myList.add(new ListNode(nodeSize));
for (int j=0; j < nodeSize; j++) {
int randomValue = new Random().nextInt(maxValue);
myList.get(i).addValue(randomValue);
}
}
logMyList(myList, "myList unsorted"); // to see what we have
// now lets sort it
myList = sortListNode(myList);
logMyList(myList, "myList sorted"); // what we have after sorting
}
/**
* Selectionsort
*/
public ArrayList<ListNode> sortListNode(ArrayList<ListNode> myList) {
ArrayList<ListNode> retList = new ArrayList<ListNode>();
for ( int i = 0; i < listsize; i++) {
retList.add(new ListNode(nodeSize));
}
int lastSmallest = myList.get(0).getValueAt(0);
while ( !myList.isEmpty() ) {
int lastJ=0, lastI=0;
for ( int i = 0; i < myList.size(); i++) {
for (int j=0; j < myList.get(i).getSize(); j++) {
if ( myList.get(i).getValueAt(j) <= lastSmallest ) {
lastSmallest = myList.get(i).getValueAt(j);
lastJ = j;
lastI = i;
//log("Found smallest element at <"+i+","+j+"> (" + lastSmallest + ")");
}
}
}
myList.get(lastI).removeValue(lastJ);
if ( myList.get(lastI).getSize() == 0 )
myList.remove(lastI);
// add value to new list
for ( int i = 0; i < listsize; i++) {
if ( retList.get(i).getSize() < retList.get(i).getMaxSize() ) {
retList.get(i).addValue(lastSmallest);
break;
}
}
lastSmallest = Integer.MAX_VALUE;
}
return retList;
}
public class ListNode {
private ArrayList<Integer> values = new ArrayList<Integer>();
private int maxSize;
public ListNode(int maxSize) {
this.maxSize = maxSize;
}
public ArrayList<Integer> getValues() {
return values;
}
public int getMaxSize() {
return maxSize;
}
public int getSize() {
return values.size();
}
public int getValueAt(int position) {
if ( position < values.size())
return values.get(position);
else
throw new IndexOutOfBoundsException();
}
public void addValue(int value) {
values.add(value);
}
public void removeValue(int position) {
if ( position < values.size()) {
values.remove(position);
} else
throw new IndexOutOfBoundsException();
}
}
}
Here we go. The trivial solution consist in extracting all the elements of each array node and store them in a single big array, sort that big array (using Bubble Sort, Quick Sort, Shell Sort, etc.) and finally reconstruct the linked list of arrays with the the sorted values. I am almost sure that is not exactly what are you looking for.
If you want to sort the numbers in place, I can think of the following algorithm:
As others have commented, you need a comparison function that determines if a node A goes before a node B. The following algorithm use the first idea but for each pair of nodes, e.g. A->[3, 9, 7] and B->[1, 6, 8] becomes [1, 3, 6, 7, 8, 9] and finally A->[1,3, 6] and B->[7, 8, 9]. If we apply this rearrangement for each possible pair will end up with a sorted linked list of arrays (I have no proof, though).
A = head;
while (A.hasNext()) {
arrayA = A.getArray();
B = A.getNext();
while (B.hasNext()) {
arrayB = B.getArray();
// concatenate two arrays
int[] C = new int[arrayA.size() + arrayB.size()];
int i;
for (i = 0; i < arrayA.size(); i++)
C[i] = arrayA[i];
for ( ; i < arrayA.size() + arrayB.size(); i++)
C[i] = arrayB[i-arrayA.size()];
// sort the new arrays using agains Bubble sort or any
// other method, or Arrays.sort()
Arrays.sort(C);
// now return the sorted values to the two arrays
for (i = 0; i < arrayA.size(); i++)
arrayA[i] = C[i];
for (i = 0; i < arrayB.size(); i++)
arrayB[i] = C[i+arrayA.size()];
}
}
This is kind of pseudo code because I haven't worked with linked lists in Java but I think you get the idea.
NOTE: I haven't tested the code, it may contain horrors.
I've been tasked with turning this code into a reverse sort, but for the life of me cannot figure out how to do it. These are my sort, findlargest and swap methods. I have a feeling I am missing something glaringly obvious here, any help would be really appreciated.
public static void sort(String[] arr)
{
for (int pass = 1; pass < arr.length; pass++)
{
int largestPos = findLargest(arr, arr.length - pass);
if (largestPos != arr.length - pass)
{
swap(arr, largestPos, arr.length - pass);
}
}
}
public static int findLargest(String[] arr, int num)
{
int largestPos = 0;
for (int i = 1; i <= num; i++)
{
if (arr[i].compareToIgnoreCase(arr[largestPos]) > 0)
{
largestPos = i;
}
}
return largestPos;
}
public static void swap(String[] arr, int first, int second)
{
String temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
}
Don't reinvent the wheel -
String[] strs = {"a", "b", "d", "c", "e"};
Arrays.sort(strs, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
System.out.println(Arrays.toString(strs));
[e, d, c, b, a]
Follow up from A. R. S.'s answer:
You could use a custom comparator if you are allowed to use the Arrays.Sort method...
Arrays.sort(stringArray, new Comparator<String>() {
#Override
public int compare(String t, String t1) {
return -t.compareToIgnoreCase(t1); //reverse the comparison, while ignoring case
}
});
Can you just turn findLargest to findSmallest, like this:
public static void sort(String[] arr) {
for (int pass = 1; pass < arr.length; pass++) {
int largestPos = findSmallest(arr, arr.length - pass);
if (largestPos != arr.length - pass) {
swap(arr, largestPos, arr.length - pass);
}
}
}
public static int findSmallest(String[] arr, int num) {
int largestPos = 0;
for (int i = 1; i <= num; i++) {
if (arr[i].compareToIgnoreCase(arr[largestPos]) < 0) {
largestPos = i;
}
}
return largestPos;
}
public static void swap(String[] arr, int first, int second) {
String temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
I think This is the one you need (if you don't think about collection framework).
public static void main(String args[]) {
String [] arr ={"abc","bac","cbc"};
String temp="";
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[j].compareTo(arr[i]) > 0){
temp = arr[i] ;
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(String val:arr){
System.out.println(val);
}
}
Output is
cbc
bac
abc
you can use Arrays.sort(arr) to sort in alphabetical order.
and then reverse it.
public static void sort(String[] arr) {
Arrays.sort(arr);
for (int i=0; i<arr.length/2; i++) {
swap(arr,i,arr.length-1-i);
}
}
Try this one if you want. In your version you are moving the largest towards the end of the array, resulting in alphabetical order.
Just in case you insist on your original approach, I have made some minor changes to your code:
public static void sort(String[] arr)
{
for (int pass = 1; pass < arr.length; pass++)
{
int largestPos = findLargest(arr, pass-1);
if (largestPos != pass - 1)
{
swap(arr, largestPos, pass - 1);
}
}
}
public static int findLargest(String[] arr, int num)
{
int largestPos = num;
for (int i = num+1; i < arr.length; i++)
{
if (arr[i].compareToIgnoreCase(arr[largestPos]) > 0)
{
largestPos = i;
}
}
return largestPos;
}
The most trivial one though, as suggested by Ian Roberts, is simply Arrays.sort(arr, Collections.reverseOrder());.
So, first we need to create String array, then use Arrays.sort(String[]);, then use for to reverse sort array to reverse order.
import java.util.Arrays;
public class SortClass {
public static void main(String[] args) {
String[] arrayString = new String[5];
arrayString[0] = "Cat";
arrayString[1] = "Apple";
arrayString[2] = "Dog";
arrayString[3] = "Mouse";
arrayString[4] = "kitchen";
Arrays.sort(arrayString);
String[] arrReverse = new String[arrayString.length];
for (int i = arrayString.length - 1; i >= 0; i--) {
arrReverse[arrayString.length - 1 - i] = arrayString[i];
}
}
}
String arr[]= new String[];
String s; //input string
int count=0;
for(int i=0;i<=s.length()-k;i++){
arr[i]=s.substring(i,i+k); //using substring method
count++;
}
int i=0;
int b=count;
while(count>0){
int j=0;
while(j<b){
if((arr[i].compareTo(arr[j])>0)){
String temp= arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
j++;
}
i++;
count--;
}
for(i=0;i<b;i++)
System.out.println(arr[i]);
I'm trying to Sort an array from my ArrayList:
ArrayList<Integer> al = new ArrayList<Integer>();
al.insert(0, 4);
al.insert(1, 3);
al.insert(2, 2);
al.insert(3, 1);
SelectionSortWrappers<Integer> ss = new SelectionSortWrappers<Integer>();
ss.sort(al.elements);
ss.show(al.elements);
But when I try to access al.elements, I'm getting:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
Here is my SelectionSort Class:
public class SelectionSortWrappers<T>{
public <T extends Comparable<? super T>> void sort(T[] array){
int index;
for(int i = 0 ; i < array.length;i++){
index = i;
for(int j = i + 1; j < array.length; j++){
if (array[j].compareTo(array[index]) < 0){
index = j;
}
}
T smaller = array[index];
array[index] = array[i];
array[i] = smaller;
}
}
public void show(T[] array){
for(int i=0; i < array.length; i++){
System.out.print(array[i] + " ");
}
}
}
My ArrayList, i had to create, because is for my university project, i cannot use the Java one.
package Lists;
public class ArrayList<T> implements List<T> {
private static int MAX_SIZE = 10;
private static final int NOT_FOUND = -1;
public T[] elements;
protected int size;
public ArrayList() {
size = 0;
elements = (T[]) new Object[MAX_SIZE];
}
public T[] getArray(){
return elements;
}
public int find(T v) {
for(int i = 0; i < size; i++) {
if(v == elements[i]) {
return i;
}
}
return NOT_FOUND;
}
public T elementAt(int pos) {
if(pos >= 0 && pos < size) {
return elements[pos];
}
throw new InvalidArgumentException();
}
public void insert(int pos, T v) {
if (size == MAX_SIZE){
elements = Arrays.copyOf(elements, size * 2);
MAX_SIZE = size * 2;
}
if(pos == size) {
elements[size] = v;
}
else {
for(int i = size; i > pos; i--) {
elements[i] = elements[i-1];
}
elements[pos] = v;
}
size++;
}
public void remove(int pos) {
if(pos >= 0 && pos < size) {
for(int i = pos; i < size-1; i++) {
elements[i] = elements[i+1];
}
size--;
}
else {
throw new InvalidArgumentException();
}
}
public int size() {
return size;
}
public void show(boolean reverse) {
if (!reverse){
for(int i=0; i < size; i++){
System.out.print(elements[i] + " ");
}
} else {
for(int i=size; i >= 0; i--){
System.out.print(elements[i] + " ");
}
}
}
}
Where is the problem? My elements field is public.
You're running into the predictable erasure-versus-arrays problem caused by doing (T[]) new Object[MAX_SIZE]. You'll get a warning on that line -- that warning is warning you about exactly this problem.
Your ArrayList class is pretending an Object[] is a T[], but it really isn't -- the actual referenced array is still an Object[]. When you pull it out with al.elements, it tries to actually cast it to an Integer[] and fails.
You will have to do something ugly to deal with this -- like what the built-in java.util.Collection.toArray(T[]) has to do, for example. Alternately, you could write your sorting method to access your ArrayList directly instead of trying to work on its underlying array.