如题,这是我的jvav语法笔记
基本数据类型:
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 30 31 32 33 34 35 36 37 38 39 40 String.isEmpty () string.isBlank () string.strip (); string.stripLeading (); string.stripTrailing (); string.trim () string.repeat (times); string.lines ().forEach(System.out::println); string.equals (string2) string.split (sep) string.substring ( index1 , index2 ) string.indexOf (sub) string.toUpperCase () String msg = String.format(" abns : %d siabd %.1f" , max , avg); String msg = "as" + "asdewf" ; ''' 相关的String Builder ''' StringBuilder sb = new StringBuilder (); sb.append (); String st = sb.toString (); ''' 相关的String的拼接 join ''' String.join ("," , columns)
> Tips:如果你需要遍历整个字符串,通常更推荐先把字符串转成真正的字符数组:(如下)
1 2 3 4 char [] chars = s.toCharArray ();for (int i = 0 ; i < chars.length; i++) { char c = chars[i]; }
1 2 3 4 5 char ch = st.charAt (index);if (ch == target) {};
线性数据结构:
⼀句话总结:需要 Stack 或 Queue 时,默认选ArrayDeque 使用的时候,为了方便,全部写成offerFirst /pollLast这样first 和 last 很清楚的格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import java.util.ArrayDeque;import java.util.Deque;ArrayDeque< > ad = new ArrayDeque<>(); ad.pollFirst (); ad.pollLast (); ad.offerFirst (); ad.offerLast ();
核⼼:数组⻓度不可变,需要”变⻓”时要么 new 新数组,要么⽤ ArrayList 函数可以返回一个数组!
1 2 3 4 5 6 7 8 9 static int [] reverse (int [] arr) { int [] result = new int [arr.length]; for (int i = 0 ; i < arr.length ; i++) { result[i] = arr[arr.length - 1 - i]; } return result; }
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 30 31 32 33 34 35 36 37 38 import java.util.ArrayList; public class Main { public static void main (String[] args) { ArrayList<String> list = new ArrayList<>(); list.add ("Java" ); list.add ("Python" ); String language = list.get (0 ); list . remove (1 ); list . remove ( Integer . valueOf ( 30 ) ) ; int size = list.size (); list.set ( 1 , 25 ); list.contains (25 ); list.get ( index ); } } ''' ArrayList<int > 不合法!泛型只能⽤包装类: Integer Double String 实践选择:不确定元素个数时先⽤ ArrayList 收集,最后按需转数组 ArrayList 需要删除元素的时候,需要反向遍历 !!避免 index 的改变而引起元素的跳过!!'''
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 StringBuilder sb = new StringBuilder ("整数:100 " ); char lastChar = sb.charAt (sb.length () - 1 ); System.out.println (lastChar); sb.append (value); sb.insert (index , value); sb,delete (index1 , index2 ) ; sb.deleteCharAt (index); sb.setCharAt (index , value); sb.length (); sb.charAt (index); sb.indexOf (substring value); sb.toString ();
Three Map
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 import java.util.HashMap;HashMap<String , Integer> map = new HashMap<>(); ''' !! 注意 在 HashMap 的逻辑里,键(Key)是唯一的标识符,而值(Value)只是挂在键上的数据。 我们可以知道hashMap 查找key 是o (1 ) 但是查找 value 仍是全表查询,为o (n) 具有不对称性 ''' ''' !! 如果我需要“根据值快速查找”怎么办? 如果你发现你的程序频繁需要根据 Value 找 Key,或者频繁检查某个 Value 是否存在,且数据量巨大,那么单纯的 HashMap 就不是最优解了。业界常用的方案:双向映射(Bi-Map):手动维护两个 HashMap。Map<Key, Value> forwardMap<Value, Key> backward这样两边查询都是 O (1 ),代价是占用两倍内存,且每次 put 时要操作两个表。 ''' map.put ("a" , 95 ); map.put ("a" , 97 ); map.get ("a" ); map.getOrDefault ("b" , 0 ); freq.put (w, freq.getOrDefault (w, 0 ) + 1 ); map.containsKey ("v" ); map.containsValue (0 ); map.remove ("a" ); map.size (); map.keySet () map.values () ''' tip:keySet () 和 values () 排列的顺序是依据hashCode 的排列顺序来的(hashMap内部是数组 + 链表/红黑树的形式,所以插入的顺序和具体遍历时的顺序是不一样的 ''' for ( Map.Entry < String , Integer > e : map.entrySet ( ) ) { String key = e.getKey (); int val = e.getValue (); }
1 2 LinkedHashMap<String , Integer> lhm = new LinkedHashMap<>();
一般的 hashmap 的一个节点 包含的内容是 : hashCode + key + value + next (hash crash 时指向下一个同hashcode 节点的 指针) 这个linkedhashmap 中一个节点: hashcode + key + value + next + before + after 这个before 和 after 是根据数据实际的put的顺序修改的 在循环遍历的时候 ,是按照这个双向链表来进行的
默认选择HashMap即可
支持 hashmap的所有的操作, 也是实现了Map接口
不同的是 , treemap 是一颗二叉树 (基于红黑树), 不是数组 , treemap 是按照 key 的字典序排列的 所以treemap在实现 hashmap的查找功能的时候: get(k) 的复杂度是 o ( log n ) containsKey(k)复杂度也是 o(log n)
1 2 3 4 5 6 7 8 9 10 11 TreeMap<String , Integer> tm = new TreeMap<>(); firstKey (); lastKey (); firstEntry (); lastEntry ();
Three Set: 需要去重? ├── 不需排序 → HashSet ├── 需要排序 → TreeSet └── 需要保持插⼊顺序 → LinkedHashSet
hashSet 是只有 键 的hashmap ,去除了重复的key
1 2 3 4 5 6 7 8 9 10 11 12 HashSet<Student> set = new HashSet<>() set.add (k); set.contains (k); set.remove (k); set.size (); retainAll ();set1. retainAll (set2) ; 这时set1中就变成了set1 与 set2的交集
none
1 2 3 4 5 TreeSet<Integer> ts = new TreeSet<>(); ts.add (k); first () ; last ();
输入输出/文件读入写入: 个人最常用的三个:
1 2 3 4 5 6 7 8 9 BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); BufferedReader br = Files.newBufferedReader (Paths.get (path (具体给出的路径))); BufferedReader br = Files.newBufferedReader (Paths.get (path (具体给出的路径)),StandardOpenOption.CREATE,StandardOpenOption.APPEND); BufferedWriter br = Files.newBufferedWriter (Paths.get (path (具体给出的路径)));
之前的笔记:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 try (BufferedReader br = new BufferedReader (new FileReader ("in.txt" ))) { String line; while ((line = br.readLine ()) != null) { process (line); } } try (BufferedWriter bw = new BufferedWriter (new FileWriter ("out.txt" ))) { bw.write ("hello" ); bw.newLine (); } Scanner sc = new Scanner (System.in); int n = sc.nextInt ();System.out.printf ("n = %d%n" , n); import java.io.*;!!!!!1. Scanner Scanner sc = new Scanner (System.in); String st = sc.next (); int num = sc.nextInt (); sc.close (); 2. BufferedReader BufferedReader br = new BufferedReader (new InputStreamReader (System.in)); String input = br.readLine (); ''' 在 Java 中,凡是涉及到 readLine () 的操作,编译器都会强制要求你处理可能发生的 IOException。最简单的修正方法: 这个需要在main的方法后面加一个throws IOException 报错信息大概长这样: unreported exception java.io.IOException; must be caught or declared to be thrown''' try (BufferedReader br = new BufferedReader (new FileReader ("data.txt" ))) { String line; while ((line = br.readLine ()) != null) { System.out.println (line); } } catch (IOException e) { e.printStackTrace (); } BufferedReader br = Files.newBufferedReader (Paths.get (path)); String line = br.readLine (); List<String> lines = readAllLines (path); BufferedWriter bw = Files.newBufferedWriter (Paths.get (path)) bw.write (line); bw.write ("\n" ); BufferedWriter bw = Files.newBufferedWriter (Paths.get (path) , StandardOpenOption.CREATE br.write (line); BufferedReader br = Files.newBufferedReader (Paths.get (src))); BufferedWriter bw = Files.newBufferedWriter (Paths.get (dst))); String line = br.readLine (); bw.write (line); ''' tips: 有时候写入 bw.newLine ();不好用 就用 bw.write ("\n" ); '''
有关追加/覆盖更为详细的版本:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 try ( BufferedWriter bw = new BufferedWriter ( new FIleWriter ( " 写入的文件名" ) ) ) { bw.write ( " " ); bw.newLine (); } try (PrintWriter pw = new PrintWriter ( " 写入文件名" ) ) { pw.println ( " " ); pw.printf (" %d " , 123 ) ; } Files.write ( Path,get ( " 写入文件名 " ) , Arrays.asList ( " " , " " ) ) ; FileWriter fw = new FileWriter ("test.txt" , false ); BufferedWriter bw = new BufferedWriter (fw); PrintWriter pw = new PrintWriter (fw); FileWriter fw = new FileWriter ("test.txt" , true ); BufferedWriter bw = new BufferedWriter (fw); PrintWriter pw = new PrintWriter (fw); 追加 FileWriter fw = new FileWriter ( " " , true ); Files.write ( path, Arrays.asList ("新的一条日志内容" ), StandardOpenOption.CREATE, StandardOpenOption.APPEND ); try ( BufferedReader br = new BufferedReader ( new FileReader ( " .txt" ) ) ) { operate } try ( BufferedReader br = …… ; BufferedWriter bw = …… ){}
files文件读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import java.nio.file.*;List<String> lines = Files.readAllLines ( Paths.get ("data.txt" ) ); String content = Files.readString ( Paths.get ( " 文件名" )); try ( Stream < String > stream = Files.lines ( Paths.get (" 文件名 " ) ) ) { stream .filter ( l -> l.contains ( " 筛选的需要包含的内容" ) ) .forEach(System.out :: println ); }
sort: 1 2 Collections.sort (result); return result;
异常: try - catch 捕获异常
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 30 31 32 33 34 35 36 37 38 public class ExceptionObjectDemo { public static void main (String[] args) { try { String str = null; System.out.println (str.length ()); } catch (NullPointerException e) { System.out.println ("e 的类型: " + e.getClass ().getName ()); System.out.println ("e 的字符串表示: " + e); System.out.println ("e 的哈希码: " + System.identityHashCode (e)); } } } try {}catch ( err1 ){}catch (err2 e) {}''' 常见异常:FileNotFoundException IOException EOFException到达流末尾 UnsupportedEncodingException编码不⽀持 SecurityException权限不⾜ 对于不同操作系统的文件传输:明确规定编码的类型!!!! 铁律:跨平台代码必须指定编码 import java.nio.charset.StandardCharsets;new InputStreamReader ( new FileInputStream ( " " ) , StandardCharsets.UTF_*);'''
函数:(lambda) private \ static \ public 访问修饰符 -> 封装 通过 private 隐藏属性,再提供 public 的方法来修改,你就可以在方法里加上校验逻辑。 无返回值:
1 2 3 static void printLine (String msg) { System.out.println (">>> " + msg); }
值传递(Pass by Value):Java 永远传递值的副本,函数内修改形参不影响实参
返回函数的函数(高阶函数)
1 2 3 4 5 6 7 public Function<Integer, Integer> createAdder (int increment) { return (Integer x ) -> x + increment; } Function<Integer , Integer> addFive = createAdder (5 );
抽象为⾼阶函数 sum (define (sum term a next b) (if (> a b) 0 (+ (term a) (sum term (next a) next b)))) term :函数参数,对每项求值 next :函数参数,计算下⼀项的位置
⽤ sum 重写三个过程 (define (sum-integers a b) (sum (lambda (x) x) a (lambda (x) (+ x 1)) b)) (define (sum-cubes a b) (sum cube a (lambda (x) (+ x 1)) b)) (define (sum-pi a b) (sum (lambda (x) (/ 1.0 (* x (+ x 2)))) a (lambda (x) (+ x 4)) b))
如果你已经给一个动作起好了名字(比如 define (cube x) (* x x x)),你就可以直接用这个名字。
如果你还没给动作起名字,或者这个动作很简单、只用一次,你就用 lambda 现写一个“匿名函数”。
在 Java 的 Lambda 表达式(list -> …)中,如果逻辑超过一行,你需要使用大括号 {} 并显式使用 return 关键字。