0

Scenario : I have two array list whit application details. One ArrayList have collection of all applications and the second ArrayList have the collection of selected applications. And I have to remove selected applications from All Application List. For this I used ArrayList.removeAll function.

Problem : ArrayList.removeAll is working absolutely fine but one problem is that when there is one application in selected application array list from two app with same name (but other properties are different) eg. AngryBirds... it removes both apps from list.

I am using it like this :

  mInstalledApplicationList = new ArrayList<App>();

        mInstalledApplicationList.addAll(ApplicationList.mInstalledAppList);
        Log.e(TAG, "Total Installed App Size : " + ApplicationList.mInstalledAppList.size());

        mInstalledApplicationList.removeAll(ApplicationList.mSelecteddAppList);
        Log.e(TAG, "Filtered Installed App Size : " + mInstalledApplicationList.size());

and my APP collection class is :

import java.util.Comparator;
import java.util.List;

import android.content.ComponentName;
import android.content.Intent;
import android.graphics.drawable.Drawable;

public class App implements Comparable<App> {

    private String title;

    private String packageName;

    private String versionName;

    private int versionCode;

    private String app_class;

    private String installDate;

    private int installDateMilli;

    private List<String> appPermissions;

    private Drawable mIcon;

    public Intent intent;

    // ordinary getters and setters

    public Drawable getmIcon() {
        return mIcon;
    }

    public void setmIcon(Drawable mIcon) {
        this.mIcon = mIcon;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getDateMilli() {
        return installDateMilli;
    }

    public void setDateMilli(int DateMilli) {
        this.installDateMilli = DateMilli;
    }

    public List<String> getAppPermissions() {
        return appPermissions;
    }

    public void setAppPermissions(String appPermission) {
        this.appPermissions.add(appPermission);
    }

    public String getInstallDate() {
        return installDate;
    }

    public void setInstallDate(String installDate) {
        this.installDate = installDate;
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public String getVersionName() {
        return versionName;
    }

    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }

    public int getVersionCode() {
        return versionCode;
    }

    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }

    public String getAppClass() {
        return app_class;
    }

    public void setAppClass(String app_class) {
        this.app_class = app_class;
    }

    final void setActivity(ComponentName className, int launchFlags) {
        intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setComponent(className);
        intent.setFlags(launchFlags);
    }

    @Override
    public int compareTo(App app) {

        return 0;
    }

    public static Comparator<App> AppNameComparator = new Comparator<App>() {

        public int compare(App app1, App app2) {

            String AppName1 = app1.getTitle().toUpperCase();
            String AppName2 = app2.getTitle().toUpperCase();

            // ascending order
            return AppName1.compareTo(AppName2);

            // descending order
            // return fruitName2.compareTo(fruitName1);
        }

    };

    public static Comparator<App> AppDateComparator = new Comparator<App>() {

        public int compare(App app1, App app2) {

            int AppName1 = 0;
            int AppName2 = 0;

            AppName1 = app1.installDateMilli;
            AppName2 = app2.installDateMilli;

            return AppName2 - AppName1;

        }

    };

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof App)) {
            return false;
        }

        App that = (App) o;
        return title.equals(that.title)
                && intent.getComponent().getClassName()
                        .equals(that.intent.getComponent().getClassName());
    }

    @Override
    public int hashCode() {
        int result;
        result = (title != null ? title.hashCode() : 0);
        final String name = intent.getComponent().getClassName();
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}

** I have updated my App Class. This is my App class**

SOLUTION

I have solved my problem by changing equals and hashCode methods like this :

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof App)) {
        return false;
    }

    App that = (App)o;
    return title.equals(that.title) && intent.getComponent().getClassName().equals(that.intent.getComponent().getClassName()) && packageName.equals(that.packageName);
}

@Override
public int hashCode() {
    int result;
    result = (title != null ? title.hashCode() : 0);
    final String name = intent.getComponent().getClassName();
    int pkg_code = (packageName != null ? packageName.hashCode() : 0);
    result = 31 * result + pkg_code + (name != null ? name.hashCode() : 0);
    return result;
}

Thank you everyone for you help.

4
  • 3
    And what does your compareTo implementation look like? Commented Mar 7, 2013 at 7:16
  • 1
    @Jon Skeet, if I remember well, ArrayList uses equals for object comparison, not compareTo Commented Mar 7, 2013 at 7:26
  • 1
    @vmironov: True, true. So, what does the equals implementation look like? (My guess is that it's just on title...) Commented Mar 7, 2013 at 7:27
  • I have updated my app class. Please check Commented Mar 7, 2013 at 8:13

1 Answer 1

2

You need to implement equals method for your App class properly. For you the probably best solution is to use packageName as unique identifier of your app:

@Override
public boolean equals(Object o) {

    if (o == this) {
        return true;
    }

    if (!(o instanceof App)) {
        return false;
    }

    App app = (App)o;
    return TextUtils.equals(app.packageName, this.packageName);

}
Sign up to request clarification or add additional context in comments.

2 Comments

package name is surely better as it also doesn't change with used language etc.
I found that I have to match App Title, Package and App Class. I was matching only Title and Class. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.