如何在ArrayList中搜索字符串

34

我想在一个ArrayList中搜索字符串。我的ArrayList包含:

ArrayList <String> list = new ArrayList(); 
list.add("behold");
list.add("bend");
list.add("bet");
list.add("bear");
list.add("beat");
list.add("become");
list.add("begin");

现在我想搜索 "bea",并且它应该返回一个包含 "bear""beat" 的列表。如何实现?

11个回答

31
 List <String> list = new ArrayList();  
           list.add("behold"); 
           list.add("bend"); 
           list.add("bet"); 
           list.add("bear"); 
           list.add("beat"); 
           list.add("become"); 
           list.add("begin");

           List <String> listClone = new ArrayList<String>(); 
           for (String string : list) {
               if(string.matches("(?i)(bea).*")){
                   listClone.add(string);
               }
           }
        System.out.println(listClone);

它能工作,但如果列表包含Bear,则不匹配。 - Romi
2
你只需要更改正则表达式,比如你想匹配小写字母'b'和大写字母'B',那么就将"(bea)."替换为"(b|B)(ea)."。 - Abhishek
1
有另一种方法可以使上述表达式不区分大小写,使用"(?i)(bea).*"。 - Abhishek

20

遍历您的列表并执行contains或startswith。

ArrayList<String> resList = new ArrayList<String>();
String searchString = "bea";

for (String curVal : list){
  if (curVal.contains(searchString)){
    resList.add(curVal);
  }
}

你可以把这个放在一个方法里。contains用来检查它是否在列表中。你也可以选择使用startswith。


应该把 String curVal : list 改为 String curVal resList,并且只有当curVal不在列表中时才将其添加到列表中,是吗? - Michael Sims

17

如今,Java 8允许使用一行函数式解决方案来代替原有的解决方案,这样做更加简洁、快速,而且更加容易理解:

List<String> list = new ArrayList<>();
list.add("behold");
list.add("bend");
list.add("bet");
list.add("bear");
list.add("beat");
list.add("become");
list.add("begin");

List<String> matches = list.stream().filter(it -> it.contains("bea")).collect(Collectors.toList());

System.out.println(matches); // [bear, beat]

在 Kotlin 中甚至更容易:

val matches = list.filter { it.contains("bea") }

2
流需要 Android Api 级别 > 24。 - Adil Soomro
错误。它需要24或更大的值。(>=) - John Lord

9

使用 java.util.HashSet 可能更容易。例如:

  List <String> list = new ArrayList<String>(); 
  list.add("behold");
  list.add("bend");
  list.add("bet");

  //Load the list into a hashSet
  Set<String> set = new HashSet<String>(list);
  if (set.contains("bend"))
  {
    System.out.println("String found!");
  }

8

由于您的列表似乎没有排序,因此必须遍历其元素。对每个元素应用startsWith()contains()方法,并将匹配项存储在辅助列表中。完成后返回辅助列表。


2
更好的方法是对数组中的每个字符串元素使用matches()方法。这将帮助您通过正则表达式搜索任何模式。

0

尝试使用Google guava库 获取更多信息--> https://github.com/google/guava

Iterable<String> result = Iterables.filter(yourListContainStringsYouWantToSearch, Predicates.containsPattern(search));
Log.i("resultsInList", "performSearch:\n"+ Lists.newArrayList(result.iterator()));

0
我见过的最好的顺序:
// SearchList is your List  
// TEXT is your Search Text
// SubList is your result

                    ArrayList<String> TempList = new ArrayList<String>(
                            (SearchList));
                    int temp = 0;
                    int num = 0;
                    ArrayList<String> SubList = new ArrayList<String>();
                    while (temp > -1) {
                        temp = TempList.indexOf(new Object() {
                            @Override
                            public boolean equals(Object obj) {
                                return obj.toString().startsWith(TEXT);
                            }
                        });
                        if (temp > -1) {
                         SubList.add(SearchList.get(temp + num++));
                         TempList.remove(temp);
                        }
                    }

2
你可以使用 .equals 或 .contains 来代替 .StartsWith。 - Hamidreza Sadegh

0

首先,您必须将AdapterArrayList中的内容复制到tempsearchnewArrayList中(将ListView项目添加到tempsearchnewArrayList中),因为只有这样才能比较搜索文本是否出现在Arraylist中。

创建临时数组列表后,添加以下代码。

    searchEditTextBox.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }
        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            String txt = charSequence.toString().trim();
            int txtlength = txt.length();
            if (txtlength > 0) {
                AdapterArrayList = new ArrayList<HashMap<String, String>>();
                for (int j = 0; j< tempsearchnewArrayList.size(); j++) {
                    if (tempsearchnewArrayList.get(j).get("type").toLowerCase().contains(txt)) {
                        AdapterArrayList.add(tempsearchnewArrayList.get(j));
                    }
                }
            } else {
                AdapterArrayList = new ArrayList<HashMap<String, String>>();
                AdapterArrayList.addAll(tempsearchnewArrayList);
            }
            adapter1.notifyDataSetChanged();
            if (AdapterArrayList.size() > 0) {
                mainactivitylistview.setAdapter(adapter1);
            } else {
                mainactivitylistview.setAdapter(null);
            }

        }
        @Override
        public void afterTextChanged(Editable editable) {

        }
    });

0
List <String> list = new ArrayList();  
           list.add("behold"); 
           list.add("bend"); 
           list.add("bet"); 
           list.add("bear"); 
           list.add("beat"); 
           list.add("become"); 
           list.add("begin");

           List <String> listClone = new ArrayList<String>(); 
           Pattern pattern = Pattern.compile("bea",Pattern.CASE_INSENSITIVE); //incase u r not concerned about upper/lower case
           for (String string : list) {
               if(pattern.matcher(string).find()) {
                   listClone.add(string);
                   continue;
               }
           }
        System.out.println(listClone);

1
尽管这段代码可能回答了问题,但提供有关它如何以及/或者为什么解决该问题的额外上下文信息将提高答案的长期价值。 - morten.c
很简单,我编译了一个Pattern对象(Pattern.compile("bea",Pattern.CASE_INSENSITIVE)),其中'bea'是我的输入,并且我希望它忽略搜索模式的大小写。接下来,我将此模式与列表1中的所有字符串逐个匹配,并通过find()方法检查是否至少有1个匹配项,如果有,则将匹配的字符串添加到新列表listClone中。 - Rishabh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接