目录
一、Lambda表达式
1.1简介
1.2使用场景
1.3Lambda表达式的使用条件
1.4Lambda表达式的语法
1.5Lambda表达式的精简
二、方法引用
2.1基本概念
2.2使用条件
2.3语法格式
2.4静态方法引用
2.5特定对象的实例方法
2.6构造函数的方法引用
三、包装类
3.1概念
3.2包装类的使用
3.3包装类的适用场景
四、Math类
五、日期时间类
5.1LocalDate类
5.2LocalTime类
5.3LocalDateTime类
5.4其他
六、random类
6.1Random对象的生成
6.2常用方法
6.3简单应用
七、字符串类
7.1创建方法
7.2常见方法
7.2.1equals(Object anObject): 将此字符串与指定的对象比较
7.2String Length. length() method
7.3parseXxx()方法
7.4将其他类型的数据转化为字符串
7.5转换大小写
7.6.查找
7.7String的遍历
7.8提取字符串
八、StringBuilder类
8.1构造方法
8.2StringBuilder和String之间的相互转换
8.3 常用方法
Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加简洁。
替代匿名内部类:在Java 8之前,如果你想要传递一个函数,通常需要使用匿名内部类。但是,使用Lambda表达式可以更加简洁地实现相同的功能。
简化集合操作:Java 8引入了Stream API,它允许你使用Lambda表达式来简化集合操作,例如过滤、映射和聚合。
事件处理:在许多图形用户界面框架中,你可以使用Lambda表达式来定义事件处理器。
延迟执行:有时候,你可能希望延迟执行某些代码。例如,在日志记录中,你可以使用Lambda表达式来定义一个日志消息生成器,然后在需要记录日志时才调用它。
总之,Lambda表达式可以用于许多场景,它可以帮助你简化代码并提高可读性。
首先,都是接口;
其次,接口中有且只有一个接口,才可以使用lambda表达式
1.接口中只有一个抽象方法的接口,叫做函数式接口
2.如果是函数式接口,那么就可以用@FunctionalInterface注解标识
1.标准格式:
(参数列表) -> {代码}2.格式说明:
- 小括内的语法与传统方法参数列表一致,没有参数就留空,有多个参数就用逗号分隔- 【->】 是新引入的语法格式,代表指向动作
- 大括号内的语法与传统方法体要求一致
package test;
public class Test04 {
public static void main(String[] args) {
//使用lambda表达式实现接口
//无参
// Test test = () -> {
// System.out.println("test");
// };
//有参
// Test test = (name,age) -> {
// System.out.println(name+age+"岁了!");
// };
// test.test("小新",18);
//有参+返回值
Test test = (name,age) -> {
System.out.println(name+age+"岁了!");
return age + 1;
};
int age = test.test("小新",18);
System.out.println(age);
}
}
//无参
//interface Test{
// public void test();
//}
//有参 无返回值
//interface Test{
// public void test(String name,int age);
//}
//有参 有返回值
interface Test{
public int test(String name,int age);
}
Lambda表达式的精简
无参数:如果Lambda表达式不接受任何参数,你可以使用一对空括号来表示:
() -> System.out.println("Hello World")
一个参数:如果Lambda表达式只接受一个参数,你可以省略括号:
x -> x * x
多个参数:如果Lambda表达式接受多个参数,你需要使用括号将它们括起来:
(x, y) -> x + y
表达式主体:如果Lambda表达式的主体只包含一个表达式,你可以省略大括号和
return
关键字:
(x, y) -> x + y
代码块主体:如果Lambda表达式的主体包含多条语句,你需要使用大括号将它们括起来,并使用
return
关键字来返回结果:
(x, y) -> { int sum = x + y; return sum; }
参数的类型
由于在接口的方法中,已经定义了每⼀个参数的类型是什么。而且在使用lambda表达式实现接口的时候,必须要保证参数的数量和类 型需要和接口中的方法保持⼀致。因此,此时lambda表达式中的参数的类型可以省略不写。
注意点:
如果需要省略参数的类型,要保证:要省略, 每⼀个参数的类型都必须省略不写。绝对不能出现,有的参数类型省略了,有的参数类型没有省略。
如果Lambda表达式的主体只包含一个表达式,那么你可以省略大括号和
return
关键字。在这种情况下,Lambda表达式会自动返回表达式的结果。BiFunction
add = (x, y) -> x + y; int result = add.apply(2, 3); // 5
方法引用是 Java 8 中的一种新特性,它用于引用函数式接口的方法。它是 lambda 表达式的简洁易读形式。每当您使用 lambda 表达式仅引用方法时,都可以用方法引用替换 lambda 表达式1。
Java 中有四种方法引用:静态方法、特定对象的实例方法、特定类型的任意对象的实例方法和构造函数
方法引用通常用于创建简单的 lambda 表达式,通过引用现有方法。每当您使用 lambda 表达式仅引用方法时,都可以用方法引用替换 lambda 表达式。
方法引用使用一对冒号 ::
有现成的方法可以完成你想要传递到其他代码的某个动作
静态方法引用是指类中定义的静态方法。语法和示例如下,描述了在 Java 中引用静态方法的过程。
语法:ContainingClass::staticMethodName
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用 lambda 表达式
numbers.forEach(number -> System.out.println(number));
// 使用静态方法引用
numbers.forEach(System.out::println);
// 使用普通方法
for (int number : numbers) {
System.out.println(number);
}
}
}
Lambda 表达式:Lambda 表达式是 Java 8 中引入的一种新特性,它允许我们将函数作为方法参数传递。Lambda 表达式可以使代码更简洁易读,但有时可能不够直观。
静态方法引用:静态方法引用是一种特殊类型的 lambda 表达式,它通过引用现有方法来创建简单的 lambda 表达式。静态方法引用通常比 lambda 表达式更简洁易读。
普通方法:普通方法是指使用传统的 for 循环或 while 循环来遍历集合并执行操作。普通方法通常比 lambda 表达式和静态方法引用更直观,但可能不够简洁。
特定对象的实例方法引用是指使用特定对象的实例方法。这种方法引用允许我们在 lambda 表达式中引用现有对象的实例方法。
语法:object::instanceMethod
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 创建一个学生列表
List students = new ArrayList<>();
students.add(new Student("Alice", 90));
students.add(new Student("Bob", 80));
students.add(new Student("Charlie", 70));
students.add(new Student("David", 60));
// 使用Lambda表达式来排序列表
System.out.println("按照分数升序排序(Lambda表达式):");
Collections.sort(students, (a, b) -> a.getScore() - b.getScore());
System.out.println(students);
// 使用特定对象的实例方法来排序列表
System.out.println("按照分数升序排序(方法引用):");
StudentComparator comparator = new StudentComparator();
Collections.sort(students, comparator::compare);
System.out.println(students);
// 使用普通方法来排序列表
System.out.println("按照分数升序排序(静态方法):");
Collections.sort(students, Main::compareStudentByScore);
System.out.println(students);
}
// 定义一个学生类
static class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return name + ":" + score;
}
}
// 定义一个比较器类
static class StudentComparator {
public int compare(Student a, Student b) {
return a.getScore() - b.getScore();
}
}
// 定义一个比较学生分数的方法
public static int compareStudentByScore(Student a, Student b) {
return a.getScore() - b.getScore();
}
}
构造函数的方法引用的语法与静态方法引用和实例方法引用类似,都是使用::
操作符。不同之处在于,构造函数的方法引用使用类名和new
关键字来表示,而不是方法名。
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
List numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
// Lambda表达式实现
int sumOfSquares1 = numbers.stream()
.mapToInt(x -> x * x)
.sum();
System.out.println("Lambda表达式实现: " + sumOfSquares1);
// 构造函数的方法引用实现
Function square = Main::square;
int sumOfSquares2 = numbers.stream()
.mapToInt(square::apply)
.sum();
System.out.println("构造函数的方法引用实现: " + sumOfSquares2);
// 普通方法实现
int sumOfSquares3 = numbers.stream()
.mapToInt(Main::square2)
.sum();
System.out.println("普通方法实现: " + sumOfSquares3);
}
// 普通方法
public static int square2(int x) {
return x * x;
}
// 构造函数的方法引用
public static int square(int x) {
return new Integer(x * x);
}
}
基本类型数据不是对象,而有时需要使用对象或可引用的类型,完成操作 Java为每种基本数据类型提供了一个包装类(Wrapper Classes) 这些类可以将基本类型的数据`包装`成对象
使用包装类,我们可以完成许多操作,例如将基本数据类型转换为字符串,将字符串转换为基本数据类型,比较两个基本数据类型的值等。
public class WrapperClassExample2 {
public static void main(String[] args) {
int number = 123;
String numberString = Integer.toString(number);
System.out.println(numberString);
}
}
这个例子中,我们使用了Integer.toString
方法将整数123
转换为字符串"123"
。
此外,包装类还提供了一些常量和静态方法来操作基本数据类型。例如,Integer
类提供了MAX_VALUE
和MIN_VALUE
常量来表示整数的最大值和最小值,以及bitCount
方法来计算一个整数的二进制表示中1的个数。
1.作为引用类型声明使用
2.与字符串相互转换的方法
3.基本数字类型间的转换;也可以用强制转换
java.lang包中的Math类为更高级的数学计算提供了方法和常量 java.lang下为Java基本包,不需要显式import引入成员
创建方法
LocalDate today = LocalDate.now();
System.out.println(today);
常用方法
LocalDate
类提供了许多方法来处理日期。下面是一些常用的方法:
now
:静态方法,用于获取当前日期。of
:静态方法,用于根据年份、月份和日期创建一个LocalDate
对象。getYear
:用于获取日期的年份。getMonthValue
:用于获取日期的月份。getDayOfMonth
:用于获取日期的日期。plusDays
:用于在日期上增加指定天数。minusDays
:用于在日期上减少指定天数。plusMonths
:用于在日期上增加指定月数。minusMonths
:用于在日期上减少指定月数。plusYears
:用于在日期上增加指定年数。minusYears
:用于在日期上减少指定年数。
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
System.out.println(today);
LocalDate birthday = LocalDate.of(1990, 1, 1);
System.out.println(birthday);
LocalDate nextWeek = today.plusDays(7);
System.out.println(nextWeek);
LocalDate nextMonth = today.plusMonths(1);
System.out.println(nextMonth);
LocalDate nextYear = today.plusYears(1);
System.out.println(nextYear);
}
}
LocalTime
类LocalTime
类是Java 8中新的日期和时间API的一部分,它表示一个时间,不包含日期信息。它提供了一些方法来获取和修改时间的各个部分,例如小时、分钟和秒。
LocalTime
类提供了许多方法来处理时间。下面是一些常用的方法:
now
:静态方法,用于获取当前时间。of
:静态方法,用于根据小时、分钟和秒创建一个LocalTime
对象。getHour
:用于获取时间的小时。getMinute
:用于获取时间的分钟。getSecond
:用于获取时间的秒。plusHours
:用于在时间上增加指定小时数。minusHours
:用于在时间上减少指定小时数。plusMinutes
:用于在时间上增加指定分钟数。minusMinutes
:用于在时间上减少指定分钟数。plusSeconds
:用于在时间上增加指定秒数。minusSeconds
:用于在时间上减少指定秒数。
import java.time.LocalTime;
public class LocalTimeMethodsExample {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println(now);
LocalTime time = LocalTime.of(9, 30, 0);
System.out.println(time);
LocalTime nextHour = now.plusHours(1);
System.out.println(nextHour);
LocalTime nextMinute = now.plusMinutes(1);
System.out.println(nextMinute);
LocalTime nextSecond = now.plusSeconds(1);
System.out.println(nextSecond);
}
}
LocalDateTime
类是Java 8中新的日期和时间API的一部分,它表示一个日期和时间。它提供了一些方法来获取和修改日期和时间的各个部分,例如年份、月份、日期、小时、分钟和秒。
Calendar
类是Java中的一个抽象类,它提供了一些方法来处理日期和时间。不过,由于它的设计存在一些问题,所以在Java 8中引入了新的日期和时间API来替代它。
Date
类是Java中的一个类,它表示一个特定的时间点,精确到毫秒。不过,由于它的设计存在一些问题,所以在Java 8中引入了新的日期和时间API来替代它。
Random类是java.util包下的一个类,它用于生成伪随机数。该类使用48位种子,通过线性同余公式进行修改。如果两个Random实例使用相同的种子创建,并且对每个实例进行相同的方法调用序列,则它们将生成并返回相同的数字序列
要生成Random对象,可以使用Random类的构造方法。Random类有两个构造方法:Random()
和Random(long seed)
。
Random()
构造方法创建一个新的随机数生成器,它的种子是根据当前时间自动设置的。例如:
Random rand = new Random();
Random(long seed)
构造方法创建一个新的随机数生成器,并使用指定的种子。例如:
Random rand = new Random(123);
nextBoolean()
: 生成一个随机的布尔值,即true或false。nextDouble()
: 生成一个随机的double类型值,范围在0.0(包含)和1.0(不包含)之间。nextFloat()
: 生成一个随机的float类型值,范围在0.0(包含)和1.0(不包含)之间。nextInt()
: 生成一个随机的int类型值。nextInt(int bound)
: 生成一个随机的int类型值,范围在0(包含)和指定的bound(不包含)之间。nextLong()
: 生成一个随机的long类型值。
需求:设计一个密码生成器,必须由6-16个字符组成,区分大小写,大写字母,小写字母,数字0-9,符号~!@#$%^&*()_+-={}|[]\:";'?,。/等尽量使用以上四类字符中的至少三种,输出带中文
import java.util.Random;
public class Main {
public static void main(String[] args) {
int length = 10; // 密码长度
String password = generatePassword(length);
System.out.println("生成的密码: " + password);
}
public static String generatePassword(int length) {
if (length < 6 || length > 16) {
throw new IllegalArgumentException("密码长度必须在6到16个字符之间。");
}
String upperCaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String lowerCaseLetters = "abcdefghijklmnopqrstuvwxyz";
String digits = "0123456789";
String specialChars = "~!@#$%^&*()_+-={}|[]\\:\";'?,./";
String allChars = upperCaseLetters + lowerCaseLetters + digits + specialChars;
Random rand = new Random();
StringBuilder password = new StringBuilder();
for (int i = 0; i < length; i++) {
int index = rand.nextInt(allChars.length());
char c = allChars.charAt(index);
password.append(c);
}
return password.toString();
}
}
这段代码定义了一个名为
PasswordGenerator
的类,其中包含一个generatePassword
方法,该方法接受一个整数参数length
,表示要生成的密码的长度。该方法首先检查密码长度是否在6到16个字符之间,如果不是,则抛出异常。然后,它定义了四个字符串变量,分别表示大写字母、小写字母、数字和特殊字符。接下来,它创建了一个Random类实例,并使用循环来生成指定长度的密码。在每次循环中,它使用Random类实例的nextInt
方法来生成一个随机索引,然后使用该索引从字符集中选择一个字符,并将其添加到密码字符串中。
String类是Java中一个非常重要的类,它用于表示字符串。String类是不可变的,这意味着一旦创建了一个String对象,它的内容就不能被修改。
有许多方法似乎修改了字符串的内容和长度,其实,这些方法真正做的,是创建并返回一个包含操作结果的新字符串
如果密码以String类型传递,会保存在内存中的常量池。如果内存被读取会造成密码泄露。因此,Java推荐密码使用char[]字符数组保存传递密码,数组使用后会被销毁,数组对象不会被复用,不会驻留在内存
当使用双引号 扩起一系列字符时,即 定义了一个字符串的字面量 编译器会创建一个string对象 无需手动使用new操作符
声明字面量字符串变量时,JVM先在字符串常量池中检索是否有相同字面量的字符串对象。有则返回引用,没有则创建字符串对象并置于池中返回引用
equals(Object anObject)
方法用于将此字符串与指定的对象比较。如果指定的对象是一个字符串,并且它与此字符串在序列上相等(即,它们具有相同的字符长度并且每个对应的字符都相等),则返回true;否则返回false。
==
运算符用于比较两个对象的引用是否相等。如果两个引用指向同一个对象,则==
运算符返回true;否则返回false。
每个包装类都提供了一个parseXxx(String s)
方法,用于将字符串转换为相应的基本数据类型。例如,Integer.parseInt(String s)
方法用于将字符串转换为int类型,Double.parseDouble(String s)
方法用于将字符串转换为double类型。
public class ParseExample {
public static void main(String[] args) {
String intStr = "123";
String doubleStr = "3.14";
int i = Integer.parseInt(intStr);
double d = Double.parseDouble(doubleStr);
System.out.println("Parsed int: " + i);
System.out.println("Parsed double: " + d);
}
}
在Java中,有几种方法可以将其他类型的数据转换为字符串:
使用
toString()
方法:许多类都重写了toString()
方法,以便返回该对象的字符串表示形式。例如,可以使用Integer.toString(int i)
方法将int类型转换为字符串,使用Double.toString(double d)
方法将double类型转换为字符串。使用字符串连接运算符
+
:可以使用字符串连接运算符+
将其他类型的数据与空字符串连接起来,从而将其转换为字符串。例如:int i = 123; String str = "" + i;
- 使用
String.valueOf()
方法:String
类提供了一个静态方法valueOf()
,它可以接受各种类型的参数,并将其转换为字符串。例如:int i = 123; String str = String.valueOf(i);
toUpperCase()
; //将此字符串中的所有字母都换为大写。toLowerCase();
//将此字符串中的所有字母都换为小写 。
indexOf(String str);//返回子字符串第一次出现的索引。
indexOf(String str, int fromIndex);//同上,从指定位置查找。lastIndexOf(String str);//返回子字符串最后一次出现的索引。
lastIndexOf(String str, int fromIndex);//同上,从指定位置查找。
要遍历字符串中的每个字符,可以使用for循环和
charAt(int index)
方法。public class TraverseStringExample { public static void main(String[] args) { String str = "Hello, world!"; for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); System.out.println("Character at index " + i + ": " + c); } } }
public class TraverseStringExample { public static void main(String[] args) { String str = "Hello, world!"; str.chars().forEach(c -> System.out.println((char) c)); } }
substring(int beginIndex, int endIndex)
;//返回从begin开始到end-1结束的子串。
StringBuilder对象与String对象相似,但它们可以被修改 StringBuilder对象被视为包含一系列可变长度数组的字符,长度和内容可以通过方法调用改变
public StringBuilder():创建一个空白可变字符串对象,它不含有任何内容
public StringBuilder(String str):根据字符串的内容,来创建可变字符串对象
public class Test{
public static void main(String[] args) {
StringBuilder str1 = new StringBuilder();
StringBuilder str2 = new StringBuilder("第二个字符串");
System.out.println(str1);
System.out.println(str2);
}
}
StringBuilder转化成String:可以通过StringBuilder#toString()方法直接实现
String转换成StringBuilder:通过StringBuilder类的构造方法实现,
public StringBuilder(String s)
public class Test{
public static void main(String[] args) {
// 创建String类型对象
String str1 = "这是第一个字符串";
// 创建一个StringBuilder对象
StringBuilder str2 = new StringBuilder("这是第二个字符串");
// String类型转换为StringBuilder对象
StringBuilder str3 = new StringBuilder(str1);
System.out.println(str3);
// StringBuilder类型转换为String对象
String str4 = str2.toString();
System.out.println(str4);
}
}
public StringBuilder append(…) :添加任意类型数据的字符串形式,并返回当前对象自身。
public String toString() :将当前StringBuilder对象转换为String对象。
public StringBuffer(or StirngBuilder) delete(int start, int end) 移除此缓冲区的子字符串中的字符
还有一些String类拥有的方法,StringBuilder照样实现了,这里不介绍了。