Collection
package com.example.demo1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
// ======================================
// 1. 初始化Collection集合(使用ArrayList实现)
// ======================================
Collection<String> fruits = new ArrayList<>();
// ======================================
// 2. 演示Collection常用方法
// ======================================
// boolean add(E e):添加元素
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");
System.out.println("添加后集合:" + fruits); // 输出:[苹果, 香蕉, 橙子]
// boolean contains(Object o):判断是否存在
System.out.println("是否包含香蕉:" + fruits.contains("香蕉")); // 输出:true
// int size():集合长度
System.out.println("当前集合大小:" + fruits.size()); // 输出:3
// boolean remove(Object o):移除指定元素
System.out.println("移除苹果结果:" + fruits.remove("苹果")); // 输出:true
System.out.println("移除后集合:" + fruits); // 输出:[香蕉, 橙子]
// boolean isEmpty():判断是否为空
System.out.println("集合是否为空:" + fruits.isEmpty()); // 输出:false
// boolean removeIf(Predicate):根据条件移除(需要Java 8+)
// 示例:移除所有包含"橙"字的元素
boolean removed = fruits.removeIf(fruit -> fruit.contains("橙"));
System.out.println("条件移除结果:" + removed); // 输出:true
System.out.println("条件移除后集合:" + fruits); // 输出:[香蕉]
// void clear():清空集合
fruits.clear();
System.out.println("清空后集合:" + fruits); // 输出:[]
// ======================================
// 3. 重新填充数据用于遍历演示
// ======================================
fruits.add("葡萄");
fruits.add("草莓");
fruits.add("芒果");
// ======================================
// 4. 迭代器遍历(Iterator)
// ======================================
Iterator<String> iterator = fruits.iterator();
System.out.println("\n迭代器遍历:");
while (iterator.hasNext()) { // 判断是否有下一个元素
String fruit = iterator.next(); // 获取当前元素并移动指针
System.out.print(fruit + " "); // 输出:葡萄 草莓 芒果
// 示例:用迭代器删除元素(安全操作)
if ("草莓".equals(fruit)) {
iterator.remove(); // 删除当前指向的元素
}
}
System.out.println("\n迭代器删除后集合:" + fruits); // 输出:[葡萄, 芒果]
// ======================================
// 5. 增强for循环(for-each)
// ======================================
System.out.println("\n增强for循环遍历:");
for (String fruit : fruits) { // 自动遍历集合中每个元素
System.out.print(fruit + " "); // 输出:葡萄 芒果
}
// ======================================
// 6. Lambda表达式的使用(结合Collection的forEach)
// ======================================
System.out.println("\nLambda表达式遍历:");
fruits.forEach(fruit -> { // Lambda表达式替代匿名内部类
System.out.print(fruit + " "); // 输出:葡萄 芒果
});
// 更简洁的Lambda写法(方法引用)
// fruits.forEach(System.out::print);
}
}
能使用 Lambda 表达式,需满足以下条件
1. 目标类型为函数式接口
Lambda 表达式只能用于函数式接口的上下文。函数式接口指的是仅包含一个抽象方法的接口。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Predicate<T>
被 @FunctionalInterface
注解标记,表明它是函数式接口,且只有一个抽象方法 test(T t)
。所以,removeIf
方法的参数位置可使用 Lambda 表达式。
2. 参数类型兼容
Lambda 表达式的参数类型要和函数式接口中抽象方法的参数类型兼容。Predicate<String>
里 test
方法的参数类型为 String
,因此 Lambda 表达式的参数类型也得是 String
,像 fruit -> fruit.contains("橙")
中,fruit
就被推断为 String
类型。
3. 返回值类型匹配
Lambda 表达式的返回值类型要和函数式接口中抽象方法的返回值类型一致。Predicate<String>
里 test
方法的返回值类型是 boolean
,所以 fruit -> fruit.contains("橙")
的返回值也得是 boolean
类型,contains
方法恰好返回 boolean
类型的值,满足要求。
不用Lambda 表达式的写法
// ... 已有代码 ...
// boolean removeIf(Predicate):根据条件移除(需要Java 8+)
// 示例:移除所有包含"橙"字的元素
boolean removed = fruits.removeIf(new java.util.function.Predicate<String>() {
@Override
public boolean test(String fruit) {
return fruit.contains("橙");
}
});
System.out.println("条件移除结果:" + removed); // 输出:true
System.out.println("条件移除后集合:" + fruits); // 输出:[香蕉]
// ... 已有代码 ...
LinkedList
package com.example.demo1;
import java.util.LinkedList; // 需要导入LinkedList类
public class a {
public static void main(String[] args) {
// 创建一个存储String类型的LinkedList
LinkedList<String> fruits = new LinkedList<>();
// 1. 演示 addFirst 和 addLast
fruits.addFirst("Apple"); // 列表变为: [Apple]
fruits.addLast("Banana"); // 列表变为: [Apple, Banana]
fruits.addFirst("Grape"); // 列表变为: [Grape, Apple, Banana]
System.out.println("添加后列表: " + fruits); // 输出: [Grape, Apple, Banana]
// 2. 演示 getFirst 和 getLast
String first = fruits.getFirst(); // 获取第一个元素
String last = fruits.getLast(); // 获取最后一个元素
System.out.println("第一个元素: " + first); // 输出: Grape
System.out.println("最后一个元素: " + last); // 输出: Banana
// 3. 演示 removeFirst 和 removeLast
String removedFirst = fruits.removeFirst(); // 删除并返回第一个元素(Grape)
String removedLast = fruits.removeLast(); // 删除并返回最后一个元素(Banana)
System.out.println("被删除的第一个元素: " + removedFirst); // 输出: Grape
System.out.println("被删除的最后一个元素: " + removedLast); // 输出: Banana
System.out.println("删除后的列表: " + fruits); // 输出: [Apple]
}
}
泛型能避免强制类型转换
package com.example.demo1;
import java.util.ArrayList;
public class a {
public static void main(String[] args) {
// 示例1:不使用泛型(原始类型)
ArrayList rawList = new ArrayList(); // 未指定泛型类型
rawList.add("Java泛型示例"); // 添加String类型元素
// 取出元素时需要强制类型转换(因为编译器不知道元素具体类型)
String rawStr = (String) rawList.get(0);
System.out.println("非泛型方式获取:" + rawStr);
// 示例2:使用泛型(指定<String>类型)
ArrayList<String> genericList = new ArrayList<>(); // 指定泛型类型为String
genericList.add("Java泛型优势"); // 编译器会检查只能添加String类型
// 取出元素时无需强制转换(编译器已知是String类型)
String genericStr = genericList.get(0);
System.out.println("泛型方式获取:" + genericStr);
}
}
TreeSet 基本使用与遍历
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// 1. 基本使用:TreeSet 自动排序且去重(元素需可比较)
TreeSet<String> fruits = new TreeSet<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grape");
fruits.add("Apple"); // 重复元素会被自动去重
System.out.println("TreeSet 内容(自然排序): " + fruits); // 输出: [Apple, Banana, Grape]
// 2. 遍历方式
// 方式1:迭代器
System.out.println("迭代器遍历:");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " "); // Apple Banana Grape
}
// 方式2:增强 for 循环
System.out.println("\n增强 for 遍历:");
for (String fruit : fruits) {
System.out.print(fruit + " "); // Apple Banana Grape
}
// 方式3:forEach + Lambda
System.out.println("\nLambda 遍历:");
fruits.forEach(fruit -> System.out.print(fruit + " ")); // Apple Banana Grape
}
}
自然排序(Comparable 接口)
若要让自定义对象存入 TreeSet
,需实现 Comparable
接口并重写 compareTo
方法(定义自然排序规则)。
// ...(接上面的 TreeSetDemo 类,添加内部类)
static class Student implements Comparable<Student> {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 重写 compareTo:按年龄升序排序(自然排序规则)
@Override
public int compareTo(Student other) {
// 核心逻辑:当前对象(this)与参数对象(other)比较
// 返回负数:this < other → 排在前面
// 返回0:相等 → 不重复存储
// 返回正数:this > other → 排在后面
return this.age - other.age;
// 若年龄相同,可追加其他字段比较(例如姓名):
// return this.age != other.age ? this.age - other.age : this.name.compareTo(other.name);
}
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + "}";
}
}
// ...(在 main 方法中添加测试代码)
// 3. 自然排序测试(Student 需实现 Comparable)
TreeSet<Student> students = new TreeSet<>();
students.add(new Student("张三", 20));
students.add(new Student("李四", 18));
students.add(new Student("王五", 22));
students.add(new Student("赵六", 18)); // 年龄与李四相同,若 compareTo 未处理姓名会被去重
System.out.println("\n\n学生集合(自然排序): " + students);
// 输出: [Student{name='李四', age=18}, Student{name='张三', age=20}, Student{name='王五', age=22}]
// 注:赵六因年龄与李四相同(compareTo 返回0)会被视为重复,未被存储
比较器排序(Comparator 接口)
若不想修改原有类(或需要自定义排序规则),可在创建 TreeSet
时传入 Comparator
比较器(覆盖自然排序规则)。
// ...(在 main 方法中添加测试代码)
// 4. 比较器排序(Comparator 覆盖自然排序)
TreeSet<Student> studentsByComparator = new TreeSet<>((s1, s2) -> {
// 自定义规则:姓名长度降序(若长度相同,按年龄升序)
int lenCompare = s2.name.length() - s1.name.length();
return lenCompare != 0 ? lenCompare : s1.age - s2.age;
});
studentsByComparator.add(new Student("张三", 20)); // 姓名长度2
studentsByComparator.add(new Student("李四四", 18)); // 姓名长度3
studentsByComparator.add(new Student("王五五五", 22));// 姓名长度4
studentsByComparator.add(new Student("赵六", 18)); // 姓名长度2
System.out.println("学生集合(比较器排序): " + studentsByComparator);
// 输出: [Student{name='王五五五', age=22}, Student{name='李四四', age=18}, Student{name='张三', age=20}, Student{name='赵六', age=18}]