contains 是 Java 中一个非常常用的方法,它的核心功能是判断一个序列(如字符串、集合等)是否包含特定的元素或子序列,根据操作对象的不同,它的具体实现和用法也略有差异。

下面我们分情况来详细说明。
String.contains() - 字符串包含子串
这是 contains 方法最常见、最基础的使用场景。
语法
public boolean contains(CharSequence s)
参数
s: 一个CharSequence对象,通常是一个字符串,你想在原字符串中查找的这个子串。
返回值
true: 如果原字符串中包含了指定的子串。false: 如果原字符串中没有找到指定的子串。
特点
- 区分大小写:
"Hello".contains("hello")会返回false。 - 返回布尔值: 它不返回子串的位置,只返回是否存在。
示例代码
public class StringContainsExample {
public static void main(String[] args) {
String sentence = "Hello, welcome to the world of Java programming!";
// 检查是否包含子串 "Java"
boolean containsJava = sentence.contains("Java");
System.out.println("句子是否包含 'Java'? " + containsJava); // 输出: true
// 检查是否包含子串 "python"
boolean containsPython = sentence.contains("python");
System.out.println("句子是否包含 'python'? " + containsPython); // 输出: false
// 区分大小写的例子
boolean containsHello = sentence.contains("hello");
System.out.println("句子是否包含 'hello'? " + containsHello); // 输出: false
boolean containsHelloCapital = sentence.contains("Hello");
System.out.println("句子是否包含 'Hello'? " + containsHelloCapital); // 输出: true
// 检查是否包含一个单词(注意空格)
boolean containsWord = sentence.contains("world");
System.out.println("句子是否包含单词 'world'? " + containsWord); // 输出: true
boolean containsNotAWord = sentence.contains("worldof");
System.out.println("句子是否包含 'worldof'? " + containsNotAWord); // 输出: false
}
}
实际应用场景
- 输入验证: 检查用户输入是否包含非法字符。
- 日志分析: 判断日志信息中是否包含特定的错误关键词。
- 条件判断: 在业务逻辑中,根据文本内容决定后续流程。
// 输入验证示例
String userInput = "admin@123";
if (userInput.contains("@")) {
System.out.println("输入格式正确,包含 '@' 符号。");
} else {
System.out.println("输入格式错误,请检查邮箱地址。");
}
Collection.contains() - 集合包含元素
当 contains 用于集合(如 List, Set, Queue)时,它的作用是判断集合中是否存在某个元素。
语法
// Collection 接口中的定义 boolean contains(Object o);
参数
o: 要在集合中查找的元素。
返回值
true: 如果集合中包含该元素。false: 如果集合中不包含该元素。
工作原理
- 对于
ArrayList等基于列表的实现,contains()方法会遍历列表中的每一个元素,并使用equals()方法进行比较。 - 对于
HashSet等基于哈希表的实现,contains()方法首先通过元素的hashCode()快速定位可能的存储位置,然后在该位置使用equals()进行精确比较,所以它的平均时间复杂度是 O(1),效率很高。
示例代码
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CollectionContainsExample {
public static void main(String[] args) {
// --- List 示例 ---
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
System.out.println("水果列表: " + fruits);
System.out.println("列表中是否包含 'Banana'? " + fruits.contains("Banana")); // true
System.out.println("列表中是否包含 'Grape'? " + fruits.contains("Grape")); // false
// --- Set 示例 ---
Set<Integer> numbers = new HashSet<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
System.out.println("\n数字集合: " + numbers);
System.out.println("集合中是否包含 20? " + numbers.contains(20)); // true
System.out.println("集合中是否包含 99? " + numbers.contains(99)); // false
// --- 重要:equals() 方法的影响 ---
// 创建一个自定义类
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 如果不重写 equals,默认使用 Object 的 equals (比较内存地址)
// 如果重写 equals,就可以根据内容进行比较
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && name.equals(person.name);
}
}
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Charlie", 40);
System.out.println("\n人员列表: " + people);
System.out.println("列表中是否包含 Alice (30)? " + people.contains(p1)); // true, 因为 equals 方法比较的是内容
System.out.println("列表中是否包含 Charlie (40)? " + people.contains(p2)); // false
}
}
Map.containsKey() 和 Map.containsValue() - 映射包含键或值
对于 Map 接口,它没有直接继承 Collection,所以没有 contains 方法,但它提供了两个功能相似的方法来分别检查键和值。

containsKey()
检查 Map 中是否包含指定的键。
// Map 接口中的定义 boolean containsKey(Object key);
containsValue()
检查 Map 中是否包含指定的值。
// Map 接口中的定义 boolean containsValue(Object value);
示例代码
import java.util.HashMap;
import java.util.Map;
public class MapContainsExample {
public static void main(String[] args) {
Map<String, Integer> studentScores = new HashMap<>();
studentScores.put("Alice", 95);
studentScores.put("Bob", 88);
studentScores.put("Charlie", 76);
System.out.println("学生分数映射: " + studentScores);
// 检查是否包含某个键
boolean hasAlice = studentScores.containsKey("Alice");
System.out.println("映射中是否包含学生 'Alice'? " + hasAlice); // true
boolean hasDavid = studentScores.containsKey("David");
System.out.println("映射中是否包含学生 'David'? " + hasDavid); // false
// 检查是否包含某个值
boolean hasScore88 = studentScores.containsValue(88);
System.out.println("映射中是否有分数 88? " + hasScore88); // true
boolean hasScore100 = studentScores.containsValue(100);
System.out.println("映射中是否有分数 100? " + hasScore100); // false
}
}
总结与最佳实践
| 方法 | 所属接口/类 | 作用 | 参数 | 返回值 | 时间复杂度 (平均) |
|---|---|---|---|---|---|
contains() |
String |
判断字符串是否包含子串 | CharSequence |
boolean |
O(n) (n为字符串长度) |
contains() |
Collection |
判断集合是否包含元素 | Object |
boolean |
O(n) (List), O(1) (HashSet) |
containsKey() |
Map |
判断映射是否包含键 | Object |
boolean |
O(1) |
containsValue() |
Map |
判断映射是否包含值 | Object |
boolean |
O(n) |
最佳实践
- 明确需求:想检查文本内容用
String.contains(),想检查集合/列表中的元素用Collection.contains(),想检查Map的键或值用containsKey()/containsValue()。 - 注意大小写:
String.contains()是区分大小写的,如果需要进行不区分大小写的检查,请先将字符串统一转为大写或小写。String text = "Hello World"; boolean containsIgnoreCase = text.toLowerCase().contains("world".toLowerCase()); // true - 理解
equals()的重要性:在使用Collection.contains()检查自定义对象时,强烈建议重写equals()和hashCode()方法,否则,contains()会默认比较对象的内存地址,这通常不是你想要的结果。 - 选择合适的集合:如果你需要频繁地检查元素是否存在,优先选择
HashSet或HashMap,而不是ArrayList,因为它们的contains操作效率要高得多。

