【问题标题】:how to check if arraylist contains a string如何检查arraylist是否包含字符串
【发布时间】:2016-03-25 00:27:57
【问题描述】:

我有这个代码,用于查找女性艺术家、男性艺术家或乐队的数量 -

 import java.util.*;


 public class FindGender {


    public static void main(String[] args) {
        // TODO code application logic here
        ArrayList < String > artists = new ArrayList < > ();
        int mnum = 0, fnum = 0, bnum = 0;
        artists.add("Beyonce (f)");
        artists.add("Drake (m)");
        artists.add("Madonna (f)");
        artists.add("Michael Jackson (m)");
        artists.add("Porcupine Tree (b)");
        artists.add("Opeth (b)");
        artists.add("FallOut Boy (b)");
        artists.add("Rick Ross {m}");
        artists.add("Chris Brown (m)");
        if (artists.contains("(b)")) bnum++;
        if (artists.contains("(m)")) mnum++;
        if (artists.contains("(f)")) fnum++;
        System.out.println("The number of male artists is: " + mnum);
        System.out.println("The number of female artists is: " + fnum);
        System.out.println("The number of bands is: " + bnum);
    }

 }

但输出显示 - 运行:

The number of male artists is: 0
The number of female artists is: 0
The number of bands is: 0
BUILD SUCCESSFUL (total time: 0 seconds)

任何帮助将不胜感激

【问题讨论】:

  • 尝试使用regex进行匹配

标签: java


【解决方案1】:

主要问题是ArrayList 上的contains 方法检查String 的完全匹配,而不是String 的一部分。相反,必须使用String.contains 检查List 中的每个String

如果您使用的是 Java 8,一种方法是将 collect ArrayList 转换为 Map 并使用 reduction 计算出现次数。假设您创建了一个单独的函数来检查 "type",如下所示:

private static String artistType(final String artist) {
    if (artist.contains("(b)")) {
        return "band";
    } else if (artist.contains("(m)")) {
        return "male";
    } else if (artist.contains("(f)")) {
        return "female";
    }
    return "unknown";
}

它使用contains-方法来确定艺术家的类型。

然后,您可以使用收集器和归约的组合来计数所有出现。

 Map<String, Integer> countByType = artists.stream()
      .collect(Collectors.groupingBy(
              FindGender::artistType,
              Collectors.reducing(0, i -> 1, Integer::sum)));

生成的地图将包含键 bandmalefemale - 与 OP 一样,这些值将是 3、4、2例子。

完整示例如下所示:

public class FindGender {
    public static void main(String[] args) {
        List<String> artists = new ArrayList<>();

        artists.add("Beyonce (f)");
        artists.add("Drake (m)");
        artists.add("Madonna (f)");
        artists.add("Michael Jackson (m)");
        artists.add("Porcupine Tree (b)");
        artists.add("Opeth (b)");
        artists.add("FallOut Boy (b)");
        artists.add("Rick Ross (m)");
        artists.add("Chris Brown (m)");


        Map<String, Integer> countByType = artists.stream()
                .collect(Collectors.groupingBy(
                        FindGender::artistType,
                        Collectors.reducing(0, i -> 1, Integer::sum)));

        System.out.println("Map: " + countByType);
    }

    private static String artistType(final String artist) {
        if (artist.contains("(b)")) {
            return "band";
        } else if (artist.contains("(m)")) {
            return "male";
        } else if (artist.contains("(f)")) {
            return "female";
        }
        return "unknown";
    }
}

输出是: Map: {band=3, female=2, male=4}

【讨论】:

    【解决方案2】:

    你在整个 List 上使用了 contains 方法,你应该在每个元素上使用它。

    在您的情况下,您可以使用for each 循环,如下例所示。

    for(String artist : artists) {
        if (artist.contains("(b)")) bnum++;
            if (artist.contains("(m)")) mnum++;
            if (artist.contains("(f)")) fnum++;
    
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用 if(string.indexOf("(f)")!=-1) fnum++ 之类的内容。这在您的代码中看起来像这样。

      public static void main(String[] args) 
      {
          // TODO code application logic here
          ArrayList<String> artists = new ArrayList<>();
          int mnum = 0, fnum = 0, bnum = 0;
          artists.add("Beyonce (f)");
          artists.add("Drake (m)");
          artists.add("Madonna (f)");
          artists.add("Michael Jackson (m)");
          artists.add("Porcupine Tree (b)");
          artists.add("Opeth (b)");
          artists.add("FallOut Boy (b)");
          artists.add("Rick Ross (m)");
          artists.add("Chris Brown (m)");
      
          for(String s:artists)
          {
              if(s.indexOf("(b)")!=-1) bnum++;
              if(s.indexOf("(m)")!=-1) mnum++;
              if(s.indexOf("(f)")!=-1) fnum++;
          }
      
          System.out.println("The number of male artists is: " + mnum);
          System.out.println("The number of female artists is: " + fnum);
          System.out.println("The number of bands is: " + bnum);
      }
      

      【讨论】:

        【解决方案4】:

        这可以通过 Java 8 流轻松完成:

        long numberOfMaleArtists = artists.stream()
            .filter(artist -> artist.contains(("(m)")))
            .count();
        

        这将从artists 列表中创建一个流,并仅过滤掉男性艺术家。然后它会计算出现次数。

        最好可以将其重构为自己的方法,该方法将要过滤的文本作为输入。然后,您可以按名称或所需的任何内容过滤艺术家。

        【讨论】:

          【解决方案5】:

          list#contains() 比较列表中的整个字符串而不是字符串的一部分,您可以这样做

          if(artists.stream().anyMatch(e -> e.contains("(b)")))   // java 8 solution
          

          即遍历列表并检查列表元素的包含。

          【讨论】:

            【解决方案6】:

            包含和包含一个字符串的一部分是不同的。为了返回 true,它应该匹配整个 String。

            这行得通

            for (String item : artists) {
                    if (item.contains("(b)")) bnum++;
                    if (item.contains("(m)")) mnum++;
                    if (item.contains("(f)")) fnum++;    
            }
            

            【讨论】:

              猜你喜欢
              • 2017-08-29
              • 2019-03-03
              • 2021-05-18
              • 2017-09-23
              • 2011-09-19
              • 2016-01-17
              • 1970-01-01
              • 2020-12-12
              • 2017-02-27
              相关资源
              最近更新 更多