0

I am not understanding that why this function is not removing the duplicate strings from the list.

private void detectApps() {
    //TODO: here set the running apps list to the Adapter
    m_processesList =AndroidProcesses.getRunningAppProcesses();
    Set<AndroidAppProcess> set= new HashSet<>();
    set.addAll(m_processesList);
    m_processesList.clear();
    m_processesList.addAll(set);
    runningAppsAdapter=new AppsAdapter(RunningAppsActivity.this,R.layout.list_item,m_processesList);
    m_listView.setAdapter(runningAppsAdapter);
    runningAppsAdapter.notifyDataSetChanged();
}
Balwinder Singh
  • 2,272
  • 5
  • 23
  • 34
sam
  • 113
  • 1
  • 9

2 Answers2

1

why this function is not removing the duplicate strings from the list?

Because you're not dealing with Strings, you're dealing with AndroidAppProcess and if you see the structure of this class:

public class AndroidAppProcess extends AndroidProcess {

  private static final boolean SYS_SUPPORTS_SCHEDGROUPS = new File("/dev/cpuctl/tasks").exists();

  /** {@code true} if the process is in the foreground */
  public final boolean foreground;

  /** The user id of this process. */
  public final int uid;
  ...

you can see that each android process is assigned a unique id. Now the possibilities are that all the processes in your list are unique. So when you convert them to Set there is no duplicate and so nothing is removed.

However, if you would have been dealing with pure String's, then definitely the duplicates would be removed, as mentioned in this answer.


Method 1

As mentioned in this answer, A HashSet uses a Map implementation, which in turn, uses hashCode() and equals() to avoid duplicate elements.

One way to solve the issue is to override hashCode() and equals() in the AndroidAppProcess Class, so that it represents your equals() criteria

For Example:

public class AndroidAppProcess extends AndroidProcess {
  ...
  ...

  @Override
  public boolean equals(Object o) {
      //return <write a logic that compare this AndroidAppProcess with another AndroidAppProcess.
  }


  @Override
  public int hashCode() {
      //return <this androidProcess name>.hashCode();
  }

}

Method 2

You can use a TreeSet instead of HashSet with a custom Comparator that compares the String arrays for equality.

private void detectApps() {
    //TODO: here set the running apps list to the Adapter
    m_processesList =AndroidProcesses.getRunningAppProcesses();

    //use TreeSet instead of HashSet
    Set<AndroidAppProcess> set= new TreeSet<>(new Comparator<AndroidAppProcess>() {
      @Override
      public int compare(AndroidAppProcess o1, AndroidAppProcess o2) {
        return /* Write a code that compares two AndroidAppProcess
        For example you can write:

        return o1.getPackageName() == o2.getPackageName();

        P.S.: I'm not sure as what's the method to get the correct name, 
        but you get the idea so you can search the library to get the correct name.
        */
      }
    });

    set.addAll(m_processesList);
    m_processesList.clear();
    m_processesList.addAll(set);
    runningAppsAdapter=new AppsAdapter(RunningAppsActivity.this,R.layout.list_item,m_processesList);
    m_listView.setAdapter(runningAppsAdapter);
    runningAppsAdapter.notifyDataSetChanged();
}
Community
  • 1
  • 1
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
  • thanks to remind me that ....can you plz tell me that how can i get the required list – sam Aug 10 '16 at 04:43
  • I have added these followings but after comparing it only returns single package name – sam Aug 10 '16 at 06:41
  • @Override public boolean equals(Object o) { return (o instanceof AndroidAppProcess) && (((AndroidAppProcess) o).getPackageName().equals(this.getPackageName())); } – sam Aug 10 '16 at 06:41
  • @Override public int hashCode() { return name.hashCode(); } – sam Aug 10 '16 at 06:41
  • inside detect apps ..... Set set= new TreeSet<>(new Comparator() { @Override public int compare(AndroidAppProcess o1, AndroidAppProcess o2) { return (o1.getPackageName().equalsIgnoreCase(o2.getPackageName()) ? 1:0); } }); – sam Aug 10 '16 at 06:43
  • ohhh got it by...............return (o1.getPackageName().equalsIgnoreCase(o2.getPackageName()) ? 0:1); – sam Aug 10 '16 at 06:45
  • @sam I've given 2 Methods in my answer, you've to implement 1 of the them, NOT both. Though I'd recommend you to go by Method 2 but I'm not sure whether `getPackageName()` would work because I've not ever worked with `AndroidAppProcess` class. Just think yourself as **What property qualifies as two objects of `AndroidAppProcess` class as equal and compare those properties in `compare()` method.** – Raman Sahasi Aug 10 '16 at 06:46
  • Same thing happening again ...nothing has changed ..what's the problem – sam Aug 10 '16 at 06:54
  • i can not chat due to raputation issue of stackoverflow – sam Aug 10 '16 at 07:03
  • getPackageName() is returnning the running process's package name – sam Aug 10 '16 at 07:04
0

Here your hashset is a list of AndroidAppProcess and although the values of the instance variables of many of its objects will be same, the objects are different. Hence the duplicates are not removed. You instead should try to use a set of strings and then the dupicates will be removed

Smit Davda
  • 638
  • 5
  • 15