考虑到还有许多公司仍然对其SDE岗位要求应试者需要有Java/C++/C类的语言技能,或是更偏好这类应试者,若是能在刷题时直接用这类语言一步到位也是更好的。即便前端人员需要重新学习,JavaScript的语法在很多方面和Java很相近,所以从JavaScript进阶到Java语法的学习曲线比较平缓。这篇文章以供转战使用Java刷题或需要巩固基础以进行算法题练习的朋友参考。
常用的包 这些包通常在OA时已经被导入在后台环境,所以一般情况下无须手动指明。
Copy 1 2 import java.util.*;import java.lang.*;
数据类型、接口和类
接口:抽象方法的集合,但没有特定方法的实现
类:通过继承接口从而继承接口的抽象方法并针对不同的方法有自己的实现
接口
特点
常用类
List
元素不唯一
LinkedList、ArrayList
Set
元素唯一
HashSet、TreeSet
Map
键值映射
HashMap、TreeMap
常用类列表 该部分仅列出了在算法题中经常用到的类型与数据结构。
类
适用情况
数组 Array
既定长度,可模拟pair、tuple等immutable容器
动态数组 ArrayList
长度动态可改的灵活数组
栈 Stack
LIFO后进先出
队列 Queue
FIFO先进先出
集合 HashSet
当需要存储非重复 元素或去重 时,优先考虑该类型,但其不保证有序
哈希表 HashMap
实现O(1)的读取与写入键值对,但其不保证有序
优先队列 PriorityQueue
利用Heap进行排序性存值
基本变量类型 - Basic Variable Types
类型
备注
byte
int
范围 -2^31 to 2^31 – 1
long
范围 -2^63 to 2^63 – 1
float
double
char
boolean
字符 - Char
用途
语法
备注
创建
char example = 'a'
注意是单引号
比较
example1 = example2
判断是否为纯数字字母
Character.isLetterOrDigit(example)
字符串 - String
用途
语法
备注
创建
String example = "Hello"
注意是双引号
根据char数组创建
String example = new String({'a', 'b'})
重复已有字符串3次以创建新字符串
const newExample = example.repeat(3);
获取长度
example.length()
获取第3位字符
example.charAt(3)
绝不能用[]
第3位字符的ascii码
(int) example.charAt(3)
将ascii码66转为对应字符
(char) 66
字符+数字实现字符递增
字符’a’第一次出现的位置
example.indexOf('a')
字符’a’最后一次出现的位置
example.lastIndexOf('a')
将字符串中的所有’a’替换为’b’
example.replace('a', 'b')
以空格为分界转换为数组
example.split(' ')
将字符串转换为字符数组
example.toCharArray()
提取前5位字符组成的子字符串
example.substring(0, 5)
将字符串全部化为小写
example.toLowerCase()
将字符串全部化为大写
example.toUpperCase()
将字符串转化为整数
Integer.parseInt(example);
将整数转化为字符串
Integer.toString(example);
判断字符串是不是纯整数
Integer.parseInt(example);
要用try-catch捕获异常
判断两个字符串是否一样
str1.equals(str2)
绝对不能用==
数字 & 数学 - Number & Math
用途
语法
备注
最大整数
Integer.MAX_VALUE
最小整数
Integer.MIN_VALUE
数组 - Array
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int [] example1 = new int []{1 , 2 , 3 }; int [] example2 = new int [3 ]; Arrays.fill(example2, 0 ); example1[0 ] = 0 ; example1.length; Arrays.equals(example1, example2); Arrays.sort(example1); Arrays.sort(example1, Collections.reverseOrder()); String text = Arrays.toString(example1); for (int num: example1){ System.out.println(num); } ArrayList<int []> arrList = new ArrayList<>(); arrList.add(new int []{1 ,2 });
动态数组 - ArrayList
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import java.util.*; ArrayList<String> example = new ArrayList<>(); example.add("a" ); example.add("c" ); example.add(1 , "b" ); String val = example.get(0 ); int firstPos = example.indexOf("b" ); int lastPos = example.lastIndexOf("b" ); List<String> sub_example = example.subList(0 , 2 ); int length = example.size(); example.remove(0 ); String converted = String.join(", " , example); example.clear(); for (String x: example){ System.out.println(x); } String[] arr = example.toArray(new String[example.size()]);
动态数组的排序默认用Collection中的sort方法,若要自定义则需要comparator。
自定义comparator的时候要注意计算时可能出现的数据溢出,建议用cast或者Object(像是Integer)来处理。
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ArrayList<Integer> example = new ArrayList<>(); Collections.sort(arraylist); Collections.sort(al, Collections.reverseOrder()); class Employee { int id; public Employee (int id) { this .id = id; } } class SortbyId implements Comparator <Employee > { public int compare (Employee a, Employee b) { return a.id - b.id; } } ArrayList<Employee> example = new ArrayList<>(); Collections.sort(example, new SortbyId()); Collections.sort(example, (Employee a, Employee b) -> { return a.id - b.id; });
栈 - Stack
Copy 1 2 3 4 5 6 7 8 import java.util.Stack;Stack<String> stack = new Stack<>(); stack.push("a" ); String top = stack.peek(); int length = stack.size(); String val = stack.pop(); stack.clear();
队列 - Queue 因避免捕获异常,不建议用add和remove操作
Copy 1 2 3 4 5 6 7 8 9 import java.util.LinkedList; import java.util.Queue; Queue<String> queue = new LinkedList<>(); queue.offer("a" ); String top = queue.peek(); int length = queue.size(); String val = queue.poll(); queue.clear();
优先队列 - PriorityQueue 因避免捕获异常,不建议用add和remove操作
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import java.util.PriorityQueue; PriorityQueue<Integer> pQueue = new PriorityQueue<>(); PriorityQueue<Integer> pQueueInit = new PriorityQueue<>(n, cmp); pQueue.offer(15 ); pQueue.offer(5 ); int top = pQueue.peek(); int length = pQueue.size(); int val = pQueue.poll(); int [] array = pQueue.toArray(); Iterator itr = pQueue.iterator(); while (itr.hasNext()) System.out.println(itr.next()); pQueue.clear();
集合 - HashSet
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import java.util.HashSet; HashSet<String> set = new HashSet<>(); set.add("a" ); set.add("b" ); set.add("c" ); boolean exists = set.contains("b" ); int length = set.size(); set.remove("b" ); for (String ptr : set) { System.out.println(ptr); } Iterator<String> i = h.iterator(); while (i.hasNext()) System.out.println(i.next()); HashSet<String> cloned_set = new HashSet<>(); cloned_set.addAll(set); set.clear();
哈希表 - HashMap
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import java.util.HashMap;HashMap<String, Integer> map = new HashMap<>(); map.put("a" , 1 ); map.put("b" , 2 ); map.put("c" , 3 ); int val = map.get("a" ); boolean keyExists = map.containsKey("c" ); boolean valExists = map.containsValue(2 ); map.remove("b" ); int size = map.size(); for (String key : map.keySet()) { System.out.println(map.get(key)); } for (int value : map.values()) { System.out.println(value); } HashMap<Integer, String> cloned_map = new HashMap<>(); cloned_map.putAll(hash_map); map.clear();
指针 Java一律遵循pass-by-value原则。白话理解,基本类型的值就直接保存在变量中,引用类型的变量保存的都是实际内容所在的地址,从而传递到函数参数的情况不一样,前者是值、后者是对应的地址,但都为相同的副本。就后者而言,如果在函数内改变了原先副本的地址(指向新对象),原传入的参数还是不变,所以一切改动都不会影响原传入参数。
this关键字指的是在当前对象的实例,涵盖对象中的成员变量或者方法。
Copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public double (int i) { i *= 2 ; } public change (int [] arr) { arr[0 ] = 100 ; } public static void main (String[] args) { int [] arr = { 1 , 2 , 3 , 4 , 5 }; int i = 100 ; double (i); change(arr); System.out.println(i); System.out.println(count[0 ]); }
所以对有时需要对参数传入的对象进行拷贝来保存特定的结果。深拷贝的方法需要手动实现,可以使用递归或是序列化的方法。这里只考虑容器单层存储基本数据类型和String(因其为final类型不可改)的浅拷贝情况,具体的方法和实现如下:
Copy 1 2 3 4 5 6 7 8 9 10 11 String[] a1 = {"a1" , "a2" }; String[] a2 = a1.clone(); List<String> newList = new ArrayList<>(oldList); newList.addAll(oldList); Map<String, Integer> newMap = new HashMap<>(oldMap); Map<String, Integer> newMap = oldMap.clone();
评论