简体   繁体   中英

sorting an arraylist of a self-made class by one of its variables and clone() will not work

ok; i am making a project for school and its a game similar to falling sand. but in order for the gravity to work i have to have the sand sorted by its position from down to up (the y variable of sand) this method should sort it; although i cannot get .clone() to work and i can't hard copy any other way i know. so i don't know how to replace all the comments in this code with something that will do what they say.

to explain how i want this to work; i want it to, one by one, remove elements from world while i place them sorted in sorted.

   public void sort(){
  //method to sort elements by y value
     ArrayList<sand> sorted=new ArrayList<sand>();
     if(world.size()!=0){
        //code to take 0 from world and place it into sorted at 0
        while(world.size()>0){
           boolean check=true;
           for(int i=0;i<sorted.size();i++){
              if(world.get(0).y<sorted.get(i).y){
                 //code to take 0 from world and place it into sorted at i
                 check=false;
              }
           }
           if(check){
              //code to take 0 from world and place it at the end
           }
        }
     }
     //code to make sorted the contents of world
  }

the error i am getting with clone is:

awesomesand.java:48: clone() has protected access in java.lang.Object
            sand a=world.get(0).clone();

and, yes world is of type sand.


EDIT

now i am getting an error on cloning.

awesomesand.java:48: incompatible types
found   : java.lang.Object
required: awesomesand.sand
            sand a=world.get(0).clone();
                                     ^

If I understand this correctly, I think you want to just sort an array. If that's the case, I don't think clone is really necessary.

Perhaps you could try using a Comparator and the Collections.sortList() method to sort your world array into the right order (where the order is determined by the implementation of the Comparator). If you need to use a different array instead of world, you could simply make a copy of world first, using the appropriate ArrayList copy constructor, or System.arraycopy, and then sort that array instead.

You are getting the clone exception because it has protected access in Object . However, sorting an ArrayList does not need clone() if you invoke the standard sorting mechanisms of Collections .

As for why you're getting the clone error, a class must override clone() with public access. This is to assure that you handle the specifics of your class:

public class Sand implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        Sand copy = (Sand) super.clone();
        // Sand specific copying done here
        return copy;
    }
}

However, easier, more efficient, and more likely correct, is to just sort the collection of sand objects directly. Here I've defined a possible version of Sand, and show the use of Collections.sort:

public class Sand {
    public int x;
    public int y;
}

public class SandComparator implements Comparator<Sand> {
    public int compare(Sand s1, Sand s2) {
        // reverse these to sort in the opposite order
        return s1.y - s2.y;
    }
    public boolean equals(Object o) {
        return o instanceof SandComparator;
    }
}

public class App {
    ArrayList<Sand> world;
    ...
    public void sort() {
        Collections.sort(world, new SandComparator());
    }
}

It's probably because "they" want to force you to think about whether you need a shallow copy of your object, or a deep copy. In your sand class, you need to implement the clone() method. You also need to implement the Cloneable interface:

public class sand implements Cloneable
{
    public Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
}

That will create a shallow copy.

Disclaimer: it's been ages since I've actively used Java, but I hope this helps.

PS: You should indeed use PascalCasing for your class names :)

Apart from what bm212 pointed out (use Collections.sort ), let me point out that your sort method will not work. You just loop through your list and put all elements smaller than your pivot at the beginning and all others at the end - which is not enough to get a sorted list.

If you really want to implement your own sort, a simple insertion or bubble sort may be your best bet:

http://en.wikipedia.org/wiki/Insertion_sort

http://en.wikipedia.org/wiki/Bubble_sort

Oh, and forget about using clone , I really doubt you need it in your case.

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