【问题标题】:Remove the duplicate strings from the runtime list从运行时列表中删除重复的字符串
【发布时间】:2016-08-10 13:51:34
【问题描述】:

我不明白为什么这个函数没有从列表中删除重复的字符串。

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();
}

【问题讨论】:

    标签: java android list hashset linkedhashset


    【解决方案1】:

    为什么这个函数没有从列表中删除重复的字符串?

    因为你不是在处理Strings,你是在处理AndroidAppProcess,如果你看到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;
      ...
    

    你可以看到每个android进程都被分配了一个唯一的id。现在可能是您列表中的所有进程都是唯一的。因此,当您将它们转换为 Set 时,没有重复,因此不会删除任何内容。

    但是,如果您一直在处理纯String,那么肯定会删除重复项,如this 答案中所述。


    方法一

    this 答案中所述,HashSet 使用Map 实现,而后者又使用hashCode()equals() 来避免重复元素。

    解决此问题的一种方法是在 AndroidAppProcess 类中覆盖 hashCode()equals(),使其代表您的 equals() 标准

    例如:

    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();
      }
    
    }
    

    方法二

    您可以使用 TreeSet 代替 HashSet 和自定义比较器来比较字符串数组是否相等。

    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();
    }
    

    【讨论】:

    • 谢谢提醒我......你能告诉我如何获得所需的清单
    • 我添加了以下内容,但比较后只返回单个包名
    • @Override public boolean equals(Object o) { return (o instanceof AndroidAppProcess) && (((AndroidAppProcess) o).getPackageName().equals(this.getPackageName())); }
    • @Override public int hashCode() { return name.hashCode(); }
    • 内部检测应用程序..... Set set= new TreeSet(new Comparator() { @Override public int compare(AndroidAppProcess o1, AndroidAppProcess o2) { return ( o1.getPackageName().equalsIgnoreCase(o2.getPackageName()) ? 1:0); } });
    【解决方案2】:

    这里你的hashset是一个AndroidAppProcess的列表,虽然它的许多对象的实例变量的值是一样的,但是对象是不同的。因此,不会删除重复项。相反,您应该尝试使用一组字符串,然后删除重复项

    【讨论】:

      猜你喜欢
      • 2014-08-02
      • 2011-12-17
      • 2019-05-05
      • 2016-10-24
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多