目录
十.排序算法比较器 lambada表达式等(intervals为二维数组)
一.Java中while循环存在多个条件时,先后顺序.
已知while循环可以存在多个条件,多个条件要同时满足时候,用&&连接,但在执行下面的语句时抛出异常:ArrayIndexOutOfBoundsException
如果更改循环条件的先后顺序就没问题了
分析原因 : 因为第一个条件抛出了异常,且两个条件是&&相连,所以没有评估第二个条件,更改先后顺序后,如果不满足第一个条件,false
,那么不管第二个条件是否为真,整个条件总是是假的;所以第二个条件不会被执行。
一些思考: 之前从没考虑过 while循环条件中存在多个条件时 条件的先后顺序会带来的影响,以后敲代码要注意考虑这些,比如设计到多个数组相关的条件时,要先判断是否越界。
二.Java中的Queue和Deque
1.队列(Queue)的一些常见用法:
(1)offer,add 区别:
一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。
(2)poll,remove 区别:
remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似, 但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。
(3)peek,element区别:
element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。
2.双向队列(Deque)的一些常见用法:
双向队列(Deque),是Queue的一个子接口,双向队列是指该队列两端的元素既能入队(offer)也能出队(poll),如果将Deque限制为只能从一端入队和出队,则可实现栈的数据结构。对于栈而言,有入栈(push)和出栈(pop),遵循先进后出原则
(1)双向队列作为堆栈数据结构
以下是Deque接口提供的用于实现堆栈的方法:
-
push() - 在双端队列的开头添加元素
-
pop() - 从双端队列的开头删除元素
-
peek() - 从双端队列的开头返回一个元素
(2)双向队列的方法
由于Deque继承了Queue接口,因此它继承了Queue接口的所有方法。
除了Queue接口中可用的方法之外,Deque界面还包括以下方法:
-
addFirst() - 在双端队列的开头添加指定的元素。如果双端队列已满,则引发异常。
-
addLast() - 在双端队列的末尾添加指定的元素。如果双端队列已满,则引发异常。
-
offerFirst() - 在双端队列的开头添加指定的元素。如果双端队列已满,则返回false。
-
offerLast() - 在双端队列的末尾添加指定的元素。如果双端队列已满,则返回false。
-
getFirst() - 返回双端队列的第一个元素。如果双端队列为空,则引发异常。
-
getLast() - 返回双端队列的最后一个元素。如果双端队列为空,则引发异常。
-
peekFirst() - 返回双端队列的第一个元素。如果双端队列为空,则返回null。
-
peekLast() - 返回双端队列的最后一个元素。如果双端队列为空,则返回null。
-
removeFirst() - 返回并删除双端队列的第一个元素。如果双端队列为空,则引发异常。
-
removeLast() - 返回并删除双端队列的最后一个元素。如果双端队列为空,则引发异常。
-
pollFirst() - 返回并删除双端队列的第一个元素。如果双端队列为空,则返回null。
-
pollLast() - 返回并删除双端队列的最后一个元素。如果双端队列为空,则返回null。
三.双层for循环中的continue和break的作用域
1.continue
在如下所示代码中在第一次循环即i=0,j=0时,程序不会执行continue后的的j+=2;会直接进行下一次内层循环,即进行i=0,j=1时的循环,以此类推。并不会影响外层循环。
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
continue;
j+=2;
}
}
2.break
在如下所示代码中在第一次循环 即i=0,j=0时,程序不会执行continue后的的j+=2;会直接进行下一次外层循环,即进行i=1,j=0时的循环,以此类推。并不会影响外层循环。
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
break;
j+=2;
}
}
总结:break、continue都只对单层循环有效 continue会结束当前循环进入下一层循环,break则会结束作用域内的整体循环。
四.HashMap
1.getOrDefault() 方法
getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。
getOrDefault() 方法的语法为:hashmap.get(Object key, V defaultValue)
- key - 键
- defaultValue - 当指定的key并不存在映射关系中,则返回的该默认值
返回 key 相映射的的 value,如果给定的 key 在映射关系中找不到,则返回指定的默认值。
eg:
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// 创建一个 HashMap
HashMap<Integer, String> sites = new HashMap<>();
// 往 HashMap 添加一些元素
sites.put(1, "Google");
sites.put(2, "Runoob");
sites.put(3, "Taobao");
System.out.println("sites HashMap: " + sites);
// key 的映射存在于 HashMap 中
// Not Found - 如果 HashMap 中没有该 key,则返回默认值
String value1 = sites.getOrDefault(1, "Not Found");
System.out.println("Value for key 1: " + value1);
// key 的映射不存在于 HashMap 中
// Not Found - 如果 HashMap 中没有该 key,则返回默认值
String value2 = sites.getOrDefault(4, "Not Found");
System.out.println("Value for key 4: " + value2);
}
}
执行以上程序输出结果为:
Value for key 1: Google
Value for key 4: Not Found
2.remove() 方法
remove() 方法用于删除hashMap 中指定键 key 对应的键值对(key-value)。
remove() 方法的语法为:hashmap.remove(Object key, Object value);
- key - 键值
- value(可选)- 键值对(key-value)中 key 对应的 value 值
如果指定 key,返回指定键 key 关联的值,如果指定的 key 映射值为 null 或者该 key 并不存在于该 HashMap 中,此方法将返回null。如果指定了 key 和 value,删除成功返回 true,否则返回 false。
eg1:
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<Integer, String> sites = new HashMap<>();
sites.put(1, "Google");
sites.put(2, "Runoob");
sites.put(3, "Taobao");
System.out.println("HashMap: " + sites);
// 删除key为2的映射关系
Boolean flag1 = sites.remove(1, "Google"); // return true
Boolean flag2 = sites.remove(2, "Weibo"); // return false
System.out.println("返回值 flag1: " + flag1);
System.out.println("返回值 flag2: " + flag2);
System.out.println("删除后的 HashMap: " + sites);
}
}
执行以上程序输出结果为:
返回值 flag1: true
返回值 flag2: false
删除后的 HashMap: {2=Runoob, 3=Taobao}
在以上实例中,我们创建了一个名为 sites 的 HashMap,该 HashMap 包含了 3 个元素。注意这两行:
Boolean flag1 = sites.remove(1, "Google"); // 存在的键值对返回 true
Boolean flag2 = sites.remove(2, "Weibo"); // 不存在的键值对返回 false
remove() 方法包含了 key 和 value,如果 HashMap 存在该 key-value 键值对返回 true,否则返回 false。
eg2:
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<Integer, String> sites = new HashMap<>();
sites.put(1, "Google");
sites.put(2, "Runoob");
sites.put(3, "Taobao");
System.out.println("HashMap: " + sites);
// 删除key为2的映射关系
String siteName = sites.remove(2); // return Runoob
System.out.println("返回值: " + siteName);
System.out.println("删除后的 HashMap: " + sites);
}
}
执行以上程序输出结果为:
HashMap: {1=Google, 2=Runoob, 3=Taobao}
返回值: Runoob
删除后的 HashMap: {1=Google, 3=Taobao}
在以上实例中,我们创建了一个名为 sites 的 HashMap,代码后面使用了 remove() 方法删除 sites 指定 key 对应的 value,返回值为该 value。
3.isEmpty()方法
判断hashMap是否为空
4.size()方法
计算hashMap中键/值对的数量
5.get()方法
获取指定key对应的value
6.clear()方法
删除hashMap中所有的键/值对
7.containsValue()方法
检查hashMap中是否存在指定的value对应的映射关系
8.containsKey()方法
检查hashMap中是否存在指定的key对应的映射关系
五.二维数组的一维表示
六.位运算
从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。
位运算概览:
1.按位与运算(&)
定义:参加运算的两个数据,按二进制位进行"与"运算。
运算规则:0&0=0 0&1=0 1&0=0 1&1=1
总结:两位同时为1,结果才为1,否则结果为0。
例如:3&5 即 0000 0011& 0000 0101 = 0000 0001,因此 3&5 的值得1。
注意:负数按补码形式参加按位与运算。
另:若将一个数&1 ,结果等于1,证明此数的最后一位是1.
与运算的用途:
1)清零
如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
2)取一个数的指定位
比如取数 X=1010 1110 的低4位,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位与运算(X&Y=0000 1110)即可得到X的指定位。
3)判断奇偶
只要根据最未位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用if ((a & 1) == 0)代替if (a % 2 == 0)来判断a是不是偶数。
4)判断是否是2的幂
一个数 n 是 2 的幂,当且仅当 n 是正整数,并且 n 的二进制表示中仅包含 1 个 1。
因此我们可以考虑使用位运算,将 n 的二进制表示中最低位的那个 1 提取出来,再判断剩余的数值是否为 0 即可。下面介绍两种常见的与「二进制表示中最低位」相关的位运算技巧。
第一个技巧是:n & (n - 1):其中 & 表示按位与运算。该位运算技巧可以直接将 n 二进制表示的最低位 1移除,它的原理如下:因此,如果 n 是正整数并且 n & (n - 1) = 0,那么 n 就是 2 的幂。
2.左移运算(<<)
左移就是把所有位向左移动几位
如: 12 << 2 意思就是12向左移动两位
12的二进制是: 0000 1100
通过这个图我们可以看出来,所有的位全都向左移动两位,然后把右边空的两个位用0补上,最左边多出的两个位去掉,最后得到的结果就是00110000 结果就是48
左移无有符号和无符号之分,都是左移之后右边补上0,最左边的符号位也直接移走消失
我们用同样的办法算 12<<3 结果是 96
8<<4 结果是 128
由此我们得出一个快速的算法 M << n 其实可以这么算 M << n = M * 2n
3.或运算符(|)
或运算符用符号“|”表示,其运算规律为:只要有一个为1,那么结果就是1,否则就为0.
4.无符号右移(>>>)
无符号右移:右移之后,无论该数为正还是为负,右移之后左边都是补上0
5.有符号右移(>>)
有符号右移:右移之后,左边的补上符号位,正数补0,负数补1
6.异或(^)
(1)任何数和 0 做异或运算,结果仍然是原来的数
(2)任何数和其自身做异或运算,结果是 0
(3)异或运算满足交换律和结合律
(4)异或是一个数学运算符。应用于逻辑运算。
(5)真异或假的结果是真,假异或真的结果也是真,真异或真的结果是假,假异或假的结果是假。就是说两个值相异结果为真。
(6)n^0=n n^n=0,即任何数与0进行异或,为它本身,两个相同的数进行异或运算,会得到0。
七.Stack 类
eg: Stack<Integer> st = new Stack<Integer>()
1.boolean empty()
判断堆栈是否为空。
2.Object peek( )
查看堆栈顶部的对象,但不从堆栈中移除它。
3.Object pop( )
移除堆栈顶部的对象,并作为此函数的值返回该对象。
4.Object push(Object element)
把项压入堆栈顶部。
5.int search(Object element)
返回对象在堆栈中的位置,以 1 为基数。
八.LinkedList和ArrayList
1.LinkedList和ArrayList的对比
LinkedList 的增加和删除的操作效率更高,而ArrayList 查找和修改的操作效率较高。
以下情况使用 ArrayList :
- 频繁访问列表中的某一个元素。
- 只需要在列表末尾进行添加和删除元素操作。
以下情况使用 LinkedList :
- 你需要通过循环迭代来访问列表中的某些元素。
- 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
2.LinkedList
eg: LinkedList<String> sites = new LinkedList<String>();
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
(1)LinkedList的特殊用法
LinkedList 实现了 Queue 接口,可作为队列使用。
LinkedList 实现了 List 接口,可进行列表的相关操作。
LinkedList 实现了 Deque 接口,可作为队列使用。
(2)LinkedList的常用方法
public boolean add(E e) | 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public void add(int index, E element) | 向指定位置插入元素。 |
public void addFirst(E e) | 元素添加到头部。 |
public void addLast(E e) | 元素添加到尾部。 |
public boolean offer(E e) | 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerFirst(E e) | 头部插入元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerLast(E e) | 尾部插入元素,返回是否成功,成功为 true,失败为 false。 |
public void clear() | 清空链表。 |
public E removeFirst() | 删除并返回第一个元素。 |
public E removeLast() | 删除并返回最后一个元素。 |
public boolean remove(Object o) | 删除某一元素,返回是否成功,成功为 true,失败为 false。 |
public E remove(int index) | 删除指定位置的元素。 |
public E poll() | 删除并返回第一个元素。 |
public E remove() | 删除并返回第一个元素。 |
public boolean contains(Object o) | 判断是否含有某一元素。 |
public E get(int index) | 返回指定位置的元素。 |
public E getFirst() | 返回第一个元素。 |
public E getLast() | 返回最后一个元素。 |
public int indexOf(Object o) | 查找指定元素从前往后第一次出现的索引。 |
public int lastIndexOf(Object o) | 查找指定元素最后一次出现的索引。 |
public E peek() | 返回第一个元素。 |
public E element() | 返回第一个元素。 |
public E peekFirst() | 返回头部元素。 |
public E peekLast() | 返回尾部元素。 |
public E set(int index, E element) | 设置指定位置的元素。 |
public Object clone() | 克隆该列表。 |
public int size() | 返回链表元素个数。 |
public Object[] toArray() | 返回一个由链表元素组成的数组。 |
public T[] toArray(T[] a) | 返回一个由链表元素转换类型而成的数组。 |
3.ArrayList
eg:ArrayList<E> objectName =new ArrayList<>();
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口。
ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
(1)ArrayList 常用方法
add() | 将元素插入到指定位置的 arraylist 中 |
clear() | 删除 arraylist 中的所有元素 |
clone() | 复制一份 arraylist |
contains() | 判断元素是否在 arraylist |
get() | 通过索引值获取 arraylist 中的元素 |
indexOf() | 返回 arraylist 中元素的索引值 |
removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
remove() | 删除 arraylist 里的单个元素 |
size() | 返回 arraylist 里元素数量 |
isEmpty() | 判断 arraylist 是否为空 |
subList() | 截取部分 arraylist 的元素 |
set() | 替换 arraylist 中指定索引的元素 |
sort() | 对 arraylist 元素进行排序 |
toArray() | 将 arraylist 转换为数组 |
toString() | 将 arraylist 转换为字符串 |
lastIndexOf() | 返回指定元素在 arraylist 中最后一次出现的位置 |
retainAll() | 保留 arraylist 中在指定集合中也存在的那些元素 |
containsAll() | 查看 arraylist 是否包含指定集合中的所有元素 |
removeRange() | 删除 arraylist 中指定索引之间存在的元素 |
replaceAll() | 将给定的操作内容替换掉数组中每一个元素 |
removeIf() | 删除所有满足特定条件的 arraylist 元素 |
forEach() | 遍历 arraylist 中每一个元素并执行特定操作 |
九.String类
1.Java substring() 方法
substring() 方法返回字符串的子字符串。
public String substring(int beginIndex)或 public String substring(int beginIndex, int endIndex)
tips:
beginIndex -- 起始索引(包括), 索引从 0 开始。
endIndex -- 结束索引(不包括)。
十.排序算法比较器 lambada表达式等(intervals为二维数组)
1.使用lambda表达式
力扣https://leetcode-cn.com/problems/merge-intervals/
传入2个变量,返回其比较的结果, v1在前,v2在后,若v2>v1则升序,如果要降序则v1<v2;
Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
2.自定义Comparator方法
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});