2013-11-27 80 views
0

我有一個ArrayList包含元素(字段是名稱和類型)。只有兩種不同的可能類型(「edu」和「ent」),我希望每個類型都可以在其自己的列表視圖中顯示。過濾器ArrayList並刪除不需要的元素

我的想法是通過每個創建具有相同的數據,然後循環兩個新的ArrayList和過濾不需要的元素是這樣的:

ListView listView_ent = (ListView) findViewById(R.id.popular_apps_list_ent); 
ArrayList<DataHolder> data_ent = data; 
for (int i = 0; i < data_ent.size(); i++) { 
    if(data_ent.get(i).getType().equals("edu")){ 
     data_ent.remove(i); 
    } 
} 
listView_ent.setAdapter(new AppsAdapter(this, data_ent)); 

ListView listView_edu = (ListView) findViewById(R.id.popular_apps_list_edu); 
ArrayList<DataHolder> data_edu = data; 
for (int i = 0; i < data_edu.size(); i++) { 
    if(data_edu.get(i).getType().equals("ent")){ 
     data_edu.remove(i); 
    } 
} 
listView_edu.setAdapter(new AppsAdapter(this, data_edu)); 

有在ArrayList的10個元素,每一種類型的5。

問題是,在兩個列表視圖的最後,有4個相同的項目以混合類型顯示。

任何想法我做錯了什麼?

+0

你有沒有探究[http://stackoverflow.com/questions/2250770/how-to-refresh-android-listview][1] ?? [1]:http://stackoverflow.com/questions/2250770/how-to-refresh-android-listview – Elorry

+0

我沒有嘗試刷新列表視圖。如果我檢查循環中發生了什麼,我可以看到由於某種未知的原因,ArrayList沒有正確過濾。 – Soriyyx

回答

3

1)中的數據複製

2)不利用我和刪除重複;使用迭代器(刪除方法:http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html#remove()),或在列表的末尾

像這樣開始:

ListView listView_ent = (ListView) findViewById(R.id.popular_apps_list_ent); 
ArrayList<DataHolder> data_ent = new ArrayList(data); 
for (int i = data_ent.size()-1; i >= 0; i--) { 
    if(data_ent.get(i).getType().equals("edu")){ 
     data_ent.remove(i); 
    } 
} 
listView_ent.setAdapter(new AppsAdapter(this, data_ent)); 

ListView listView_edu = (ListView) findViewById(R.id.popular_apps_list_edu); 
ArrayList<DataHolder> data_edu = = new ArrayList(data); 
for (int i = data_edu.size()-1; i >= 0 ; i--) { 
    if(data_edu.get(i).getType().equals("ent")){ 
     data_edu.remove(i); 
    } 
} 
listView_edu.setAdapter(new AppsAdapter(this, data_edu)); 
1

是的,作業只會將data_ent(這是一個參考)的值複製到data_edu。他們都會提到同一個對象。所以,無論你更改了任一列表中做出,相同的更改將在其他列表反映以及

這是你應該做的: -

List<Integer> data_edu = new ArrayList<Integer>(data_ent); 

,或者使用數組列表的addAll()功能。

1

ArrayList中刪除一個項目後,所有項都向下移動。您可以在i--添加remove後,或使用迭代器:

Iterator<DataHolder> i = data_edu.iterator(); 
while (i.hasNext()) { 
    DataHolder d = i.next(); 
    if (d.getType().equals(...) { 
     i.remove(); 
    } 
} 
1

在您的for循環,你可能會被跳過的項目。假設您的列表是這樣的:

list = {edu, edu, ent, ent, edu} 

您的索引變量將是i = 0list[i] == "edu"那麼你刪除它,但隨後你的列表變成:

list = {edu, ent, ent, edu} 

但你的索引變量被遞增,然後等於1和list[1] = "ent"。正如你所說的,你並沒有處理列表中的第一個元素。你跳過了索引。

希望這是明確的。

如果你在你的項目中可用公共資源的集合,您不妨使用過濾方法上CollectionUtils

CollectionUtils.filter(your_list, new Predicate() { 
     @Override 
     public boolean evaluate(Object obj) { 
      return !((DataHolder) obj).getType().equals("edu"); 
     } 
    }); 
1

拉胡爾是正確的關於列表的引用,但你還有一個問題也是如此。

ListView listView_ent = (ListView) findViewById(R.id.popular_apps_list_ent); 
ArrayList<DataHolder> data_ent = data; 
for (int i = 0; i < data_ent.size(); i++) { 
    if(data_ent.get(i).getType().equals("edu")){ 
     data_ent.remove(i); 
    } 
} 

問題是,當你刪除時,你會惹惱你的指數。你實質上是在跳過物品。考慮

{"edu", "edu", "ent"} 

一旦你拿出的第一項(索引0),第二EDU成爲新的指數爲0,但你繼續前進,並檢查索引1

嘗試使用的ListIterator http://docs.oracle.com/javase/6/docs/api/java/util/ListIterator.html

提示:

ListIterator<DataHolder> entDataIterator = data_ent.listIterator(); 
while(entDataIterator.hasNext(){ 
    if(/*whatever*/){ 
     entDataIterator.remove(); 
    } 
} 
1
  1. 你刪除循環是錯誤的。您可以使用:for(int i = data_end.size - 1,i> = 0,i--)
  2. 稍後考慮功能擴展?使用兩種以上的類型?
  3. 解決方案非常簡單。您的代碼過濾功能第一

    public List<DataHolder> filterBy(List<DataHolder> list, String type) { 
        List<DataHolder> l = new ArrayList<>(); 
        for (DataHolder h : list) { 
         if (h.getType().equals(type)) { 
          l.add(h); 
         } 
        } 
        return l; 
    } 
    

使用過濾功能:

List<DataHolder> eduList = filterBy(data, "edu"); 
    listView_edu.setAdapter(new AppsAdapter(this, eduList)); 

    List<DataHolder> entList = filterBy(data, "ent"); 
    listView_ent.setAdapter(new AppsAdapter(this, entList));