Java语法糖
Java语法
为什么专门要有一篇针对Java语法的文章呢,其实不是为了去梳理所有语法知识,而是针对算法题目这一块,有需要专门掌握的内容。比如常用的各种集合方法,注意事项。这些都是我在刷算法题目中积累的内容。
类型转换
字符串转其他
1. 字符串与数组之间的转换:
字符串转换为字符数组:
1
2String str = "Hello";
char[] charArray = str.toCharArray(); // 返回字符数组 ['H', 'e', 'l', 'l', 'o']字符数组转换为字符串:
1
2
3
4char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str = new String(charArray); // 返回字符串 "Hello"
// 或者
String str = String.valueOf(charArray); // 返回字符串 "Hello"
2. 字符串与列表之间的转换:
字符串转换为列表:
1
2String str = "Hello,World";
List<String> list = Arrays.asList(str.split(",")); // 返回列表 ["Hello", "World"]列表转换为字符串:
1
2List<String> list = Arrays.asList("Hello", "World");
String str = String.join(",", list); // 返回字符串 "Hello,World"
3. 字符串与集合之间的转换:
字符串转换为集合:
1
2
3String str = "Hello,World";
List<String> list = Arrays.asList(str.split(",")); // 返回列表 ["Hello", "World"]
Set<String> set = new HashSet<>(list); // 返回集合 {"Hello", "World"}集合转换为字符串:
1
2Set<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
类和Collection
、List
的关系:
Arrays
类专门用来操作数组,而Collection
和List
是Java集合框架中的接口,主要用来操作集合。Arrays.asList()
方法可以将一个数组转化为List
,但需要注意的是,这个方法返回的List
大小是固定的,不能增加或删除元素,因为它实际上只是对原数组的一种视图。- 另外,
List
、Set
、Queue
都是继承或实现了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 |
|
Map
put(K key, V value)
: 将指定的键值对添加到映射中。get(Object key)
: 返回与指定键关联的值。remove(Object key)
: 从映射中删除指定键及其对应的值。containsKey(Object key)
: 判断映射是否包含指定的键。containsValue(Object value)
: 判断映射是否包含指定的值。size()
: 返回映射中键值对的数量。isEmpty()
: 判断映射是否为空。keySet()
: 返回映射中所有键的集合。values()
: 返回映射中所有值的集合。entrySet()
: 返回映射中所有键值对的集合。
1 |
|
队列和栈
Java提供了Queue
接口来定义队列的行为,但它并没有提供具体的实现类。Queue
接口继承自Collection
接口,因此可以使用任何Collection
的实现类来实现队列的功能,包括List
。
栈不是直接使用List
、Map
或Set
这三种集合类型来实现的。尽管这些集合类型可以用于存储数据,但它们并没有提供专门用于栈操作的接口或方法。在 Java 中,java.util.Stack
类提供了栈的基本实现。下面是 Stack
类的常用方法列表:
void push(E item)
: 将元素压入栈顶。E pop()
: 弹出并返回栈顶元素。E peek()
: 返回栈顶元素,但不移除它。boolean empty()
: 判断栈是否为空。(注意,不是isEmpty)int search(Object o)
: 查找指定元素在栈中的位置,如果存在则返回相对于栈顶的位置(栈顶为 1),否则返回 -1。
在 Java 中,栈通常是通过数组或链表来实现的。Java 标准库中提供了两种主要的栈实现:
基于数组的实现:
java.util.Stack
类是一个基于动态数组的栈实现。它是Vector
类的一个子类,因此支持所有Vector
的操作,但通常推荐使用ArrayDeque
代替,因为ArrayDeque
是Deque
接口的实现,性能更好。1
2
3
4
5Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
int poppedElement = stack.pop();基于链表的实现:
java.util.LinkedList
类是一个双向链表实现的List
接口,也可以被用作栈。在栈的操作中,LinkedList
提供了push
(在链表头添加元素)和pop
(从链表头移除元素)等方法。1
2
3
4
5LinkedList<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 |
|
无论选择基于数组还是链表的实现,实际的选择通常取决于使用场景和性能需求。如果需要高效的栈操作,可能会选择 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)
- 删除从
start
到end-1
索引位置的字符。
- 删除从
String substring(int start)
- 返回一个新的
String
,它包含此序列当前长度的子字符串。
- 返回一个新的
String substring(int start, int end)
- 返回一个新的
String
,它包含此序列从start
到end-1
索引位置的子字符串。
- 返回一个新的
Stream流
Stream流分为1.创建Stream;2.中间操作;3.终端操作三部分。
1. 创建Stream
有多种方式可以创建Stream:
1 |
|
1 |
|
1 |
|
2. 中间操作
中间操作是对数据进行一系列处理的过程,返回的仍然是一个Stream。常见的中间操作有:
filter(Predicate<T> predicate)
:
1 |
|
map(Function<T, R> mapper)
:
1 |
|
distinct()
:去重,去掉重复的元素。
sorted()
:排序元素。
3. 终端操作
终端操作是对Stream进行最终操作,得到最终的结果。一旦终端操作执行,Stream就被消费,不能再被使用。常见的终端操作有:
forEach(Consumer<T> action)
:对每个元素执行指定操作。
1 |
|
collect(Collectors.toList())
:将Stream元素收集到一个List中。
1 |
|
count()
:返回Stream中元素的个数。
anyMatch(Predicate<T> predicate)
:判断是否至少匹配一个元素。
allMatch(Predicate<T> predicate)
:判断是否全部匹配。
noneMatch(Predicate<T> predicate)
:判断是否没有一个元素匹配。
findFirst()
和findAny()
:返回第一个元素或任意一个元素。
Lambda表达式
Lambda表达式可以看作是匿名函数的一种形式,它提供了一种简洁的方式来传递行为(方法)给方法。
Lambda表达式的基本语法如下:
1 |
|
或者
1 |
|
- 参数列表:参数可以为空或非空,如果有多个参数,用逗号分隔。
- 箭头符号
->
:箭头符号将参数列表和Lambda体分隔开。 - Lambda体:可以是表达式或语句块。如果是表达式,结果将自动返回;如果是语句块,需要使用
{}
包裹,并且需要手动指定return
语句。
1 |
|
正则表达式
正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于匹配字符串的模式描述工具。它是由字符和特殊字符组成的字符串,用于定义搜索模式。正则表达式在文本处理、字符串匹配和替换等方面非常强大,几乎所有主流编程语言都支持正则表达式操作。
以下是一些正则表达式的基本概念和常见用法:
- 普通字符: 大多数字符在正则表达式中都是普通字符,它们匹配它们自身。例如,正则表达式
abc
匹配字符串中的 “abc”。 - 元字符: 正则表达式中有一些特殊字符称为元字符,它们具有特殊的含义。例如:
.
:匹配任意一个字符(除了换行符)。^
:匹配字符串的开始。$
:匹配字符串的结束。*
:匹配前一个字符的零次或多次。+
:匹配前一个字符的一次或多次。?
:匹配前一个字符的零次或一次。[]
:字符类,匹配方括号中的任意一个字符。|
:或操作,匹配两边任意一边的内容。
- 字符类: 使用方括号
[]
来定义一个字符类,表示匹配其中的任何一个字符。例如,[aeiou]
可以匹配任何一个元音字母。 - 反义字符类: 使用
^
在字符类的开头表示反义,即匹配不在字符类中的任何字符。例如,[^0-9]
表示匹配非数字字符。 - 预定义字符类: 有一些常用的字符类有特殊的缩写,如:
\d
:匹配任意数字(相当于[0-9]
)。\w
:匹配任意字母数字字符(相当于[a-zA-Z0-9]
)。\s
:匹配任意空白字符(空格、制表符等)。
- 量词: 用来指定一个模式的匹配次数。
{n}
:匹配前一个字符恰好 n 次。{n,}
:匹配前一个字符至少 n 次。{n,m}
:匹配前一个字符至少 n 次,但不超过 m 次。
- 分组: 使用圆括号
()
可以将一系列字符作为一个整体进行处理。例如,(ab)+
可以匹配 “ab”、”abab”、”ababab” 等。 - 转义字符: 使用反斜杠
\
来转义元字符,使其失去特殊含义,变成普通字符。例如,\.
匹配实际的点而不是任意字符。 - 匹配模式: 有时需要指定匹配模式,如大小写不敏感匹配。在一些正则表达式引擎中,可以使用
i
表示不区分大小写,m
表示多行模式等。