Java-零散笔记

常识

  • Java对象和new的东西分配在堆上。

  • Java运行于虚拟机中,不同的系统环境使用对应的JVM可以跑相同的代码,因此具备跨平台性。

  • C++还依赖系统环境,因此系统环境不同时相同的代码的运行结果不一定相同,或者不能运行。

Java 程序执行

源代码由javac.exe 编译生成二进制指令(.class文件), 然后交给当前操作系统的JVM执行。

不同操作系统的JVM可以执行相同的二进制指令, 并根据当前操作系统进一步转化为机器指令。 因此源代码只需要编译一次。

JDK JRE JVM

JDK, Java Development Kid, Java开发开源工具包。

JRE, Java Runtime Environment, Java运行环境。

JVM, Java Virtual Machine, Java虚拟机。

基本类型

  • 基本类型在栈中, 不是引用。

  • 隐式类型转换只能从低内存类型向高内存类型转换,如intdouble, 而相反时必须显式转换。

  • 基本类型有对应的类,可以相互赋值, 为装箱或拆箱。

  • 浮点数默认为double, 给float赋值需要末尾加f。

    1
    float price = 12.2f; 
  • 声明数组时得到一个引用,默认为null,使用前应创建。 也可以建立基本类型数组,默认值为0.

    写法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    声明

    Type[] name;
    Type name[];

    赋值

    name = new Type[num];

    同时声明和赋值

    Type[] name = new Type[num];
    int[] a = {1, 2, 3, 4};

命名规范

包名全小写, 域名命名的包名单词反过来并用.隔开。

类名首字母大写

对象和方法首单词小写,后面单词首字母大写

常量全大写

数组声明用 Type[] name;

输出

System.out.println()

System.out.print()

静态变量和静态方法

静态变量只占用一块存储空间。 是类具有的属性, 被所有对象共享。 静态上下文不能用this。

调用方法:

  • 通过具体实例调用

  • 用类调用

    1
    Class.i

静态的变量和方法在类被加载时就分配, 在创建对象之前分配。

代码块和静态代码块

代码块在创建对象时执行, 且执行在构造方法之前。

静态代码块在类加载时执行。

String 类

  • 连接 +
  • 字符串长度 length()
  • 字符串查找 indexOf() and lastIndexOf()
  • 获取索引位置字符 charAt()
  • 获取子字符串 substring(int beginIndex, *int endIndex)
  • 去除空格 trim()
  • 替换字符串 replace(char oldChar, char newChar)
  • 判断开头结尾 startsWith(String prefix), endsWith(suffix)
  • 判断相等 s1.equals(s2)
  • 按字典序比较 s1.compareTo(s2) 若s1在s2之前返回-1
  • 大小写转换 toLowerCase() toUpperCase()
  • 字符串分割 split(String sign, int limit)sign分割, limit为匹配次数。 如果sign有多个用|连接, 如 ,|=

数组

  • 二维数组遍历

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for(int i = 0; i < a.length; i++) {
    for(int j = 0; j < a[j].length; j++) {
    ...a[i][j];
    }
    }

    for(int x[] : arr2) {
    for(int e : x) {
    ...e
    }
    }
  • 填充数组 fill(int[] a, *int fromIndex, *int toIndex, int value)

  • 排序 sort()

  • 复制 copyOf(arr, int newlength), copyOf(arr, int fromIndex, int toIndex)

  • 二分查找 binarySearch(Object[], int fromIndex, int toIndex, Object key)

    1
    2
    Arrays.sort(a);
    int index = Arrays.binarySearch(a, 4);

别名

Java通过引用获取变量

对于 C = D , C和D指向同一个实例,只是名字不同,为“别名”(aliasing).

== 比较的是引用是否指向同一实例,若比较两实例的内容, 用 equals()。 (n1.equals(n2))

构造器

  • 可以用this来使用构造器
    1
    2
    this();
    this(1);

垃圾回收

System.gc()请求执行垃圾回收

权限修饰符

  • private 类内部访问
  • 无修饰(friendly) 包内任意访问
  • protected 包内任意访问,不同包仅子类访问
  • public 任意访问

输出对象

将一个对象格式化输出, 需要重写对象的toString方法。

1
2
3
4
5
6
7
class Student {
int id, age, grade;
String name;
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ",grade=" + grade + "]";
}
}

JAVA全是用类和对象, 所有类都继承Object类, 都有toString 方法。 推测所有类在输出时都会自动调用 toString 方法。

容器

常用有三种容器: Map, Set, List, 分别包含 HashMap, TreeMap, HashSet, TreeSet, ArrayList, LinkedList

同类的容器用法基本相同, 不同的是内部实现和效率问题。

ArrayList为可变数组, 加入、删除较慢, 随机访问较快。 而LinkedList则是链表结构。

定义一般可用向上转型的方式定义。

List

1
2
3
4
5
6
7
8
9
10
11
12
13
List<Student> list = new ArrayList<Student>();
list.add(new Student(1, "Zhangsan", 28, 98));
list.sort((a, b)->a.name.compareTo(b.name));
list.forEach(System.out::println);

for(int i = 0; i < list.size(); i++) {
String str = list.get(i);
}

Iterator<String> it = list.iterator();
while(it.hasNext()) {
String str = (String) it.next();
}

Map

1
2
3
HashMap<Integer, String> map = new HashMap<>();
map.put(number, name);
System.out.println(map.get(1));

static应用

这样定义一个 library对象。

1
2
3
4
5
6
public class Library {
private static Library library = new Library();
public static Library getLibrary() {
return library;
}
}

便可以在其他地方使用 Library.getLibrary() 来获得这个对象。

相当于整个包的全局变量。

控制台输入

Scanner

1
2
3
Scanner scanner = new Scanner(System.in);
int number = scanner.nextInt();
String name = scanner.next();

interface+Lambda表达式

用接口和Lambda表达式来实现各种功能。 写起来很优雅。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class T5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int arr[] = {1, 2, 4, 8, 3, 6, 7};
supplier test = (int[] a) -> {
int res = a[0];
for(int i = 1; i < a.length; i++) {
res = res > a[i] ? res : a[i];
}
return res;
};

System.out.println(test.max(arr));
}
interface supplier {
int max(int[] a);
}
}

可变长参数

将参数打包成数组, 也可以直接传入数组。

可变长参数必须放在最后一位。

1
2
3
void test(int... arr){

}

封装

将成员变量隐藏, 通过定义方法有选择性的提供获得成员变量的方法或修改变量。 通过封装可以使变量更加安全。

final

final类不能被继承, final方法不能被子类重写, final变量只能被赋值一次。

推荐对不发生变化的变量加final关键字, JVM会对其做优化。

其他

将字符串数字转为整型。

Integer.parseInt(number)