Java语法糖

Java语法

为什么专门要有一篇针对Java语法的文章呢,其实不是为了去梳理所有语法知识,而是针对算法题目这一块,有需要专门掌握的内容。比如常用的各种集合方法,注意事项。这些都是我在刷算法题目中积累的内容。

类型转换

字符串转其他

1. 字符串与数组之间的转换:

  • 字符串转换为字符数组:

    1
    2
    String str = "Hello";
    char[] charArray = str.toCharArray(); // 返回字符数组 ['H', 'e', 'l', 'l', 'o']
  • 字符数组转换为字符串:

    1
    2
    3
    4
    char[] charArray = {'H', 'e', 'l', 'l', 'o'};
    String str = new String(charArray); // 返回字符串 "Hello"
    // 或者
    String str = String.valueOf(charArray); // 返回字符串 "Hello"

2. 字符串与列表之间的转换:

  • 字符串转换为列表:

    1
    2
    String str = "Hello,World";
    List<String> list = Arrays.asList(str.split(",")); // 返回列表 ["Hello", "World"]
  • 列表转换为字符串:

    1
    2
    List<String> list = Arrays.asList("Hello", "World");
    String str = String.join(",", list); // 返回字符串 "Hello,World"

3. 字符串与集合之间的转换:

  • 字符串转换为集合:

    1
    2
    3
    String str = "Hello,World";
    List<String> list = Arrays.asList(str.split(",")); // 返回列表 ["Hello", "World"]
    Set<String> set = new HashSet<>(list); // 返回集合 {"Hello", "World"}
  • 集合转换为字符串:

    1
    2
    Set<String> set = new HashSet<>(Arrays.asList("Hello", "World"));
    String str = String.join(",", set); // 返回字符串 "Hello,World"

4. 字符串与基本类型之间的转换:

  • 字符串转其他:Integer.parseInt() Double.parseDouble() Boolean.parseBoolean()
  • 其他转字符串:String.valueOf() Integer.toString() Double.toString() Boolean.toString()

Arrays

Java语言中的Arrays类是一个工具类,位于java.util包下。这个类包含用来操作数组(例如排序和搜索)的各种静态方法。

下面是Arrays类的一些重要方法:

  • **sort()**:对数组进行排序。
  • **binarySearch()**:使用二分查找算法查找数组中的元素。
  • **equals()**:比较两个数组是否相等。
  • **fill()**:使用指定的值填充数组。
  • **asList()**:将数组转化为List

关于Arrays类和CollectionList的关系:

  • Arrays类专门用来操作数组,而CollectionList是Java集合框架中的接口,主要用来操作集合。
  • Arrays.asList()方法可以将一个数组转化为List,但需要注意的是,这个方法返回的List大小是固定的,不能增加或删除元素,因为它实际上只是对原数组的一种视图。
  • 另外,ListSetQueue都是继承或实现了Collection接口,因此有一些通用的操作,比如add、remove等,可以通过Collections类(请注意和Collection接口区分)提供的一些静态方法来操作。比如Collections.sort()可以对List进行排序。

集合方法合集

List

  • add(E element): 将指定的元素添加到列表的末尾。
  • get(int index): 返回列表中指定索引位置的元素。
  • set(int index, E element): 替换列表中指定索引位置的元素。
  • remove(int index): 删除列表中指定索引位置的元素。
  • size(): 返回列表中的元素数量。
  • isEmpty(): 判断列表是否为空。
  • contains(Object obj): 判断列表是否包含指定的元素。
  • indexOf(Object obj): 返回指定元素在列表中首次出现的索引。
  • subList(int fromIndex, int toIndex): 返回列表中指定范围的子列表。

ArrayList

ArrayList独特方法:

  • trimToSize(): 将ArrayList的容量调整为当前元素的数量,以减少内存占用。
  • ensureCapacity(int minCapacity): 增加ArrayList的容量,以确保其至少能容纳指定的最小元素数量。
  • toArray(): 返回包含ArrayList中所有元素的数组。
  • toArray(T[] array): 将ArrayList中的元素复制到指定的数组中,并返回该数组。
  • removeRange(int fromIndex, int toIndex): 移除列表中指定范围的元素。

LinkedList

LinkedList独特方法:

  • addFirst(E element): 在列表的开头插入指定的元素。
  • addLast(E element): 在列表的末尾插入指定的元素。
  • getFirst(): 返回列表的第一个元素,但不移除它。
  • getLast(): 返回列表的最后一个元素,但不移除它。
  • removeFirst(): 移除并返回列表的第一个元素。
  • removeLast(): 移除并返回列表的最后一个元素。
  • offer(E element): 在列表的末尾插入指定的元素。
  • offerFirst(E element): 在列表的开头插入指定的元素。
  • offerLast(E element): 在列表的末尾插入指定的元素。
  • poll(): 移除并返回列表的第一个元素。
  • pollFirst(): 移除并返回列表的第一个元素。
  • pollLast(): 移除并返回列表的最后一个元素。
  • peek(): 返回列表的第一个元素,但不移除它。
  • peekFirst(): 返回列表的第一个元素,但不移除它。
  • peekLast(): 返回列表的最后一个元素,但不移除它。

除了实现Deque接口外,LinkedList还实现了List接口和Queue接口,因此您可以将LinkedList用作列表或队列的实例。

Set

  • add(E element): 将指定的元素添加到集合中。
  • remove(Object obj): 从集合中删除指定的元素。
  • contains(Object obj): 判断集合是否包含指定的元素。
  • size(): 返回集合中的元素数量。
  • isEmpty(): 判断集合是否为空。
  • clear(): 清空集合中的所有元素。
  • iterator(): 返回一个迭代器,用于遍历集合中的元素。
1
2
3
4
5
6
7
8
9
Iterator<T> iterator = set.iterator();
while (iterator.hasNext()) {
T element = iterator.next();
// 对元素进行操作
}
// 第二种
for (T element : set) {
// 对元素进行操作
}

Map

  • put(K key, V value): 将指定的键值对添加到映射中。
  • get(Object key): 返回与指定键关联的值。
  • remove(Object key): 从映射中删除指定键及其对应的值。
  • containsKey(Object key): 判断映射是否包含指定的键。
  • containsValue(Object value): 判断映射是否包含指定的值。
  • size(): 返回映射中键值对的数量。
  • isEmpty(): 判断映射是否为空。
  • keySet(): 返回映射中所有键的集合。
  • values(): 返回映射中所有值的集合。
  • entrySet(): 返回映射中所有键值对的集合。
1
2
3
4
5
6
7
8
Map<K, V> map = ...; // 假设这里是你的Map对象

for (Map.Entry<K, V> entry : map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
// 对键值对进行操作
}
// 迭代器遍历

队列和栈

Java提供了Queue接口来定义队列的行为,但它并没有提供具体的实现类。Queue接口继承自Collection接口,因此可以使用任何Collection的实现类来实现队列的功能,包括List

栈不是直接使用ListMapSet这三种集合类型来实现的。尽管这些集合类型可以用于存储数据,但它们并没有提供专门用于栈操作的接口或方法。在 Java 中,java.util.Stack 类提供了栈的基本实现。下面是 Stack 类的常用方法列表:

  1. void push(E item): 将元素压入栈顶。
  2. E pop(): 弹出并返回栈顶元素。
  3. E peek(): 返回栈顶元素,但不移除它。
  4. boolean empty(): 判断栈是否为空。(注意,不是isEmpty
  5. int search(Object o): 查找指定元素在栈中的位置,如果存在则返回相对于栈顶的位置(栈顶为 1),否则返回 -1。

在 Java 中,栈通常是通过数组或链表来实现的。Java 标准库中提供了两种主要的栈实现:

  1. 基于数组的实现: java.util.Stack 类是一个基于动态数组的栈实现。它是 Vector 类的一个子类,因此支持所有 Vector 的操作,但通常推荐使用 ArrayDeque 代替,因为 ArrayDequeDeque 接口的实现,性能更好。

    1
    2
    3
    4
    5
    Stack<Integer> stack = new Stack<>();
    stack.push(1);
    stack.push(2);
    stack.push(3);
    int poppedElement = stack.pop();
  2. 基于链表的实现: java.util.LinkedList 类是一个双向链表实现的 List 接口,也可以被用作栈。在栈的操作中,LinkedList 提供了 push(在链表头添加元素)和 pop(从链表头移除元素)等方法。

    1
    2
    3
    4
    5
    LinkedList<Integer> stack = new LinkedList<>();
    stack.push(1);
    stack.push(2);
    stack.push(3);
    int poppedElement = stack.pop();

注意:

  • 在实际使用中,更常见的是使用 Deque 接口来实现栈。Deque 是一个双端队列(Double-Ended Queue)接口,可以在两端进行插入和删除操作,因此也适用于栈的实现。ArrayDeque 类是一个 Deque 接口的实现,具有良好的性能,通常用于代替 Stack 类。
1
2
3
4
5
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
stack.push(2);
stack.push(3);
int poppedElement = stack.pop();

无论选择基于数组还是链表的实现,实际的选择通常取决于使用场景和性能需求。如果需要高效的栈操作,可能会选择 ArrayDeque,但如果在操作中需要频繁地插入和删除元素,可能会选择 LinkedList

字符串

  • length():返回字符串的长度。
  • charAt(int index):返回指定位置的字符。
  • isEmpty():检查字符串是否为空。
  • toUpperCase():将字符串转换为大写形式。
  • toLowerCase():将字符串转换为小写形式。
  • equals(Object obj):比较两个字符串是否相等。
  • equalsIgnoreCase(String anotherString):忽略大小写比较两个字符串是否相等。
  • concat(String str):将指定字符串连接到原字符串的末尾。
  • substring(int beginIndex):返回从指定位置开始到字符串末尾的子串。
  • substring(int beginIndex, int endIndex不包含):返回指定范围内的子串,。
  • split(String regex):根据给定的正则表达式将字符串拆分成字符串数组。
  • trim():去除字符串开头和结尾的空白字符。
  • replace(char oldChar, char newChar):用新字符替换字符串中的旧字符。
  • replaceAll(String regex, String replacement):使用新字符串替换满足正则表达式的部分字符串。
  • contains(CharSequence sequence):检查字符串是否包含指定的子串。
  • startsWith(String prefix):检查字符串是否以指定的前缀开头。
  • endsWith(String suffix):检查字符串是否以指定的后缀结尾。
  • indexOf(String str):返回指定子串在字符串中第一次出现的位置。
  • lastIndexOf(String str):返回指定子串在字符串中最后一次出现的位置。
  • String.format(format, args): String.format("Name: %s, Age: %d, Height: %.2f meters", name, age, height);
    • %s: 字符串
    • %d: 十进制整数
    • %f: 浮点数
    • %b: 布尔值
    • %c: 字符
    • %x: 十六进制整数
    • %n: 换行符

StringBuilder

  • int length()
    • 返回当前字符串的长度。
  • int capacity()
    • 返回StringBuilder的当前容量。
  • StringBuilder append(String str)
    • 将指定的字符串追加到此字符序列。
  • deleteCharAt(int index)
    • 删除给定索引位置的字符。
  • StringBuilder delete(int start, int end)
    • 删除从startend-1索引位置的字符。
  • String substring(int start)
    • 返回一个新的String,它包含此序列当前长度的子字符串。
  • String substring(int start, int end)
    • 返回一个新的String,它包含此序列从startend-1索引位置的子字符串。

Stream流

Stream流分为1.创建Stream;2.中间操作;3.终端操作三部分。

1. 创建Stream

有多种方式可以创建Stream:

1
2
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> streamFromList = list.stream(); // 从集合创建
1
2
codeString[] array = {"apple", "banana", "orange"};
Stream<String> streamFromArray = Arrays.stream(array); // 从数组创建
1
Stream<String> streamOfValues = Stream.of("apple", "banana", "orange"); // stream.of创建

2. 中间操作

中间操作是对数据进行一系列处理的过程,返回的仍然是一个Stream。常见的中间操作有:

filter(Predicate<T> predicate)

1
stream.filter(s -> s.startsWith("a")); // 过滤掉不符合条件的元素。

map(Function<T, R> mapper)

1
stream.map(String::toUpperCase); // 对每个元素应用函数。

distinct():去重,去掉重复的元素。

sorted():排序元素。

3. 终端操作

终端操作是对Stream进行最终操作,得到最终的结果。一旦终端操作执行,Stream就被消费,不能再被使用。常见的终端操作有:

forEach(Consumer<T> action):对每个元素执行指定操作。

1
stream.forEach(System.out::println);

collect(Collectors.toList()):将Stream元素收集到一个List中。

1
List<String> collectedList = stream.collect(Collectors.toList());

count():返回Stream中元素的个数。

anyMatch(Predicate<T> predicate):判断是否至少匹配一个元素。

allMatch(Predicate<T> predicate):判断是否全部匹配。

noneMatch(Predicate<T> predicate):判断是否没有一个元素匹配。

findFirst()findAny():返回第一个元素或任意一个元素。

Lambda表达式

Lambda表达式可以看作是匿名函数的一种形式,它提供了一种简洁的方式来传递行为(方法)给方法。

Lambda表达式的基本语法如下:

1
(parameters) -> expression

或者

1
(parameters) -> { statements; }
  • 参数列表:参数可以为空或非空,如果有多个参数,用逗号分隔。
  • 箭头符号 ->:箭头符号将参数列表和Lambda体分隔开。
  • Lambda体:可以是表达式或语句块。如果是表达式,结果将自动返回;如果是语句块,需要使用 {} 包裹,并且需要手动指定 return 语句。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 以Runnable接口为例
Runnable runnable = () -> System.out.println("Hello, Lambda!");

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 使用Lambda表达式遍历集合
names.forEach(name -> System.out.println(name));

// 使用Lambda表达式进行条件过滤
names.removeIf(name -> name.length() > 4);

// Comparator作为函数式接口使用Lambda表达式
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((s1, s2) -> s1.compareTo(s2));

正则表达式

正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于匹配字符串的模式描述工具。它是由字符和特殊字符组成的字符串,用于定义搜索模式。正则表达式在文本处理、字符串匹配和替换等方面非常强大,几乎所有主流编程语言都支持正则表达式操作。

以下是一些正则表达式的基本概念和常见用法:

  1. 普通字符: 大多数字符在正则表达式中都是普通字符,它们匹配它们自身。例如,正则表达式 abc 匹配字符串中的 “abc”。
  2. 元字符: 正则表达式中有一些特殊字符称为元字符,它们具有特殊的含义。例如:
    • .:匹配任意一个字符(除了换行符)。
    • ^:匹配字符串的开始。
    • $:匹配字符串的结束。
    • *:匹配前一个字符的零次或多次。
    • +:匹配前一个字符的一次或多次。
    • ?:匹配前一个字符的零次或一次。
    • []:字符类,匹配方括号中的任意一个字符。
    • |:或操作,匹配两边任意一边的内容。
  3. 字符类: 使用方括号 [] 来定义一个字符类,表示匹配其中的任何一个字符。例如,[aeiou] 可以匹配任何一个元音字母。
  4. 反义字符类: 使用 ^ 在字符类的开头表示反义,即匹配不在字符类中的任何字符。例如,[^0-9] 表示匹配非数字字符。
  5. 预定义字符类: 有一些常用的字符类有特殊的缩写,如:
    • \d:匹配任意数字(相当于 [0-9])。
    • \w:匹配任意字母数字字符(相当于 [a-zA-Z0-9])。
    • \s:匹配任意空白字符(空格、制表符等)。
  6. 量词: 用来指定一个模式的匹配次数。
    • {n}:匹配前一个字符恰好 n 次。
    • {n,}:匹配前一个字符至少 n 次。
    • {n,m}:匹配前一个字符至少 n 次,但不超过 m 次。
  7. 分组: 使用圆括号 () 可以将一系列字符作为一个整体进行处理。例如,(ab)+ 可以匹配 “ab”、”abab”、”ababab” 等。
  8. 转义字符: 使用反斜杠 \ 来转义元字符,使其失去特殊含义,变成普通字符。例如,\. 匹配实际的点而不是任意字符。
  9. 匹配模式: 有时需要指定匹配模式,如大小写不敏感匹配。在一些正则表达式引擎中,可以使用 i 表示不区分大小写,m 表示多行模式等。

Java语法糖
https://2536184321.github.io/2023/09/22/Java语法/
作者
cky
发布于
2023年9月22日
许可协议