简体   繁体   中英

Unable to print out ArrayList (Possible Logic Error in Code)

I am creating a MergeSort class in java that performs the MergeSort algorithm. I have tried multiple methods of printing out my final return to the console, but no matter what I have done, it prints out the gobbledeegook of any object.

Here is my pseudo code (If there are any logic errors please let me know)

/**
*merge(A, B):
*C = empty list 
*
*While A and B are not empty:
*   If the first element of A is smaller than the first element of B:
*       Remove the first element of A
*       Add it to the end of C
*   Else
*       Remove first element of B
*       Add it to the end of C
*
*If A or B still contains elements, add them to the end of C
*
*mergeSort(A):
*   if length of A is 1:
*       return A
*
*   Split A into two lists, L and R
*
*   Q = merge(mergeSort(L), mergeSort(R))
*
*   return Q
*/

And here is my actual code:

import java.util.ArrayList;

public class MergeSort {
    public static void main(String[] args) {
        ArrayList<Object> List = new ArrayList<Object>();
        List.add(new Object[]{412, 491, 312, 265, 295, 253, 278});

        ArrayList<Object> Q = MergeSort.mergeSort(List);
        MergeSort.printArrayList(Q);
    }

    @SuppressWarnings("null")
    public static ArrayList<Object> merge(ArrayList<Object> A, ArrayList<Object> B) {
        ArrayList<Object> C = null;

        while (!A.isEmpty() && !B.isEmpty()) {
            if ((int) A.get(0) < (int) B.get(0)) {
                C.add(A.get(0));
                A.remove(0);
            } else {
                C.add(B.get(0));
                B.remove(0);
            }
        }

        return C;
    }

    public static ArrayList<Object> mergeSort(ArrayList<Object> A) {
        if (A.size() == 1) {
            return A;
        }

        ArrayList<Object> L = (ArrayList<Object>) A.subList(0, A.size() / 2);
        ArrayList<Object> R = (ArrayList<Object>) A.subList(A.size() / 2 + 1, A.size() + 1);

        ArrayList<Object> Q = merge(mergeSort(L), mergeSort(R));

        return Q;
    }

    public static void printArrayList(ArrayList<Object> Q) {
        Object[] P = new Object[Q.size()];
        Q.toArray(P);

        for (Object c : P) {
            System.out.print(c.toString() + " ");
        }
    }

}

Any help would be greatly appreciated (I'm not very experienced with ArrayLists or Lists)

Here is my new code I arrived at given all of your suggestions.

import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;

public class MergeSort
{
public static void main(String[] args)
{
    List<Integer> list = new ArrayList<Integer>(); //(Arrays.asList(412, 491,  312, 265, 295, 253, 278));
    list.addAll(Arrays.asList(412,491,312,265,295,253,278));

    List<Integer> sortedList = MergeSort.mergeSort(list);
    MergeSort.printList(sortedList);
}

public static List<Integer> merge(List<Integer> firstHalf, List<Integer> secondHalf)
{
    List<Integer> mergedList = new ArrayList<>();

    while((!(firstHalf.size() == 0)) && (!(secondHalf.size() == 0)))
    {
        if((int)firstHalf.get(0) < (int)secondHalf.get(0))
        {
            mergedList.add(firstHalf.get(0));
            firstHalf.remove(0);
        }
        else
        {
            mergedList.add(secondHalf.get(0));
            secondHalf.remove(0);
        }
    }

    if(firstHalf.size() > 0)
    {
        for(Integer c : firstHalf)
        {
            mergedList.add(c);
        }
    }
    else
    {
        for(Integer c : secondHalf)
        {
            mergedList.add(c);
        }
    }



    return mergedList;
}

public static List<Integer> mergeSort(List<Integer> list)
{
    if(list.size() == 1)
    {
        return list;
    }

    List<Integer> firstHalf = list.subList(0, list.size() / 2);
    List<Integer> secondHalf = list.subList(list.size() / 2 + 1, list.size());

    List<Integer> sortedList = merge(mergeSort(firstHalf), mergeSort(secondHalf));

    return sortedList;
}

public static void printList(List<Integer> sortedList)
{
    for(Integer c : sortedList)
    {
        System.out.print(c.toString() + " ");
    }
}

}

I keep getting ConcurrentModificationException, but I'm not using any threading. The error occurs at lines 22, 66, and 14. At while((!(firstHalf.size() == 0)) && (!(secondHalf.size() == 0)))

I feel bad asking for help again because all your answers really helped me, but I haven't been able to figure this one out.

The toArray method returns a new array (therefore your P array is empty). Something like this should work:

public static void printArrayList(ArrayList<Object> Q)
{
    for(Object c : Q)
    {
        System.out.print(c.toString() + " ");
    }
}

You are initializing your list variable with a single array instead of a bunch of numbers. Therefore you end up with a two-dimensional array in the end, which you can see if you do

System.out.println(Arrays.deepToString(P)); 

Try it like this instead:

List<Object> list = new ArrayList<Object>(Arrays.asList(412, 491, 312, 265, 295, 253, 278));

This reveals a bunch of other problems in your code, like the fact that you are trying to cast a List returned by subList() to ArrayList , and that you go outside of the boundaries of your List .

Change all ArrayList reference variable to be of type List instead, and rethink your logic regarding indexes.

You should change your data structure.

new Object[]{412, 491, 312, 265, 295, 253, 278} //this will return an array of objects

and now you store it in a list as a object:

ArrayList<Object> List = new ArrayList<Object>();

then your problem is you cant access it. Change to:

ArrayList<Object[]> List = new ArrayList<Object[]>();

and then you can print it out like this:

        for(Object[] objarray : List)
            for(Object number : objarray)
                System.out.println(number);

Here is the code with some improvements:

1) Use List instead of ArrayList in left side:

List<Integer> list = new ArrayList<Integer>();

2) Don't use Object for generics but the necessery class (Integer in your case)

3) Don't use variable name straring from uppercase and not give them name with one letter. This is not informative to code reader. Give the name like this:

List<Integer> sortedList = MergeSort.mergeSort(list);

4) Init List as follow:

List<Integer> list = new ArrayList<Integer>();
list.addAll(Arrays.asList(412,491,312,265,295,253,278));

or
List<Integer> list = new ArrayList<Integer>(Arrays.asList(412,491,312,265,295,253,278));

5) list.subList(list.size() / 2 + 1, list.size());

instead of:

list.subList(list.size() / 2 + 1, list.size() + 1);

You will get java.lang.IndexOutOfBoundsException

6) You declare List<Integer> C = null ; and then accessing to it C.add(A.get(0)); . Initialize the list before accessing.

 List<Integer> C = new ArrayList<>();
 C.add(A.get(0));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM