manugupt1
manugupt1

Reputation: 2437

Finding Difference of 2 sets in Java

I have two hashsets in Java, of which I want to find the difference

I tried the following code as recommended by Oracle's doc

    HashSet<RunningTaskInfo> difference = new HashSet<ActivityManager.RunningTaskInfo>(newRunningTasks);
    HashSet<RunningTaskInfo> oldRunningTaskInfos = new HashSet<ActivityManager.RunningTaskInfo>(oldRunningTasks);
    difference.removeAll(oldRunningTaskInfos);

    for(RunningTaskInfo d : difference){
        ComponentName cn = d.baseActivity;
        Log.d("com.manugupt1.fua","Comparing : " + i + cn.getPackageName() + "****" + cn.getClassName() + "****" + cn.getShortClassName());

    }

Only those data values that are not in oldRunningTasks should be shown but I get only the elements from oldRunningTasks. Any suggestions

Upvotes: 0

Views: 217

Answers (1)

Victor Caveda
Victor Caveda

Reputation: 686

EDIT: Adding Matt's comments

RemoveAll is comparing objects pointers instead of the content, and that's why it's not able to find any coincidences.

You can check this by watching the return value of

difference.removeAll(oldRunningTaskInfos);

(false means "no coincidences")

Probably the best approach would be encapsulating RunningTask into an object that overrides equals() and hashcode() methods, and then invoke removeAll. Consider the following sample code that do the same but using List's:

// Getting two snapshots
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> oldRunningTasks=am.getRunningTasks (100);
List<ActivityManager.RunningTaskInfo> newRunningTasks=am.getRunningTasks (100);

// We add a new fake task to test that removeAll() is working
ActivityManager.RunningTaskInfo fakeTask=new ActivityManager.RunningTaskInfo ();
fakeTask.baseActivity=new ComponentName("Fake","Fake");
fakeTask.id=1234;
newRunningTasks.add(fakeTask);


// Converting to lists of Comparable objects and get the differences. 
List<RunningTaskInfoComparable> list_difference = convertToComparable(newRunningTasks);
List<RunningTaskInfoComparable> list_oldRunningTaskInfos = convertToComparable(oldRunningTasks);
boolean res=list_difference.removeAll(list_oldRunningTaskInfos);


for(RunningTaskInfoComparable d : list_difference){
    ComponentName cn = d.getBaseActivity();
    Log.d("com.test.tasks","Comparing List: "  + cn.getPackageName() + "****" + cn.getClassName() + "****" + cn.getShortClassName());
 }

where RunningTaskInfoComparable is implemented like this:

public class RunningTaskInfoComparable  {

    android.app.ActivityManager.RunningTaskInfo runningTaskObject; 

    public RunningTaskInfoComparable (android.app.ActivityManager.RunningTaskInfo obj)
    {
        runningTaskObject=obj;
    }


    // Observer
    public ComponentName getBaseActivity(){
        return runningTaskObject.baseActivity;
    }



    @Override
    public int hashcode()
    {

        int result = HashCodeUtil.SEED;

        // More data could be added to the hash...
            result = HashCodeUtil.hash( result, runningTaskObject.id);
        return result;
    }


    @Override
    public boolean equals(Object obj) {

        if (!(obj instanceof RunningTaskInfoComparable)) {
            return false;
          }

        // Criteria: Same task id means same entity
        return (runningTaskObject.id==((RunningTaskInfoComparable)obj).runningTaskObject.id);
    }


}

and convertToComparable looks like:

private List<RunningTaskInfoComparable> convertToComparable (List<ActivityManager.RunningTaskInfo> _original)
{
    List<RunningTaskInfoComparable> retList=new ArrayList<RunningTaskInfoComparable>();

    for(RunningTaskInfo t : _original){
        RunningTaskInfoComparable tc = new RunningTaskInfoComparable(t);
        retList.add(tc);
    }
    return retList;
}

Upvotes: 2

Related Questions