Java 学习笔记 —— 基础部分

1. 第一个 Java 程序

打开终端,输入

$ vim HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        ystem.out.println("Hello world!");		// static提供了这样一个特性,无需建立对象,就可以启动
    }
}

在终端将上述代码存放到 Hello.java中,使用 javac Hello.java编译代码,生成一个 Hello.class文件,接着使用 java Hello来运行程序。

Java 源程序与编译型运行区别

基础语法

  • 对大小写敏感
  • 类名应当大写开头
  • 方法名要小写开头
  • 源文件名要和类名相同
  • 标识符由字母、下划线或 $ 打头,不能是关键字

2. Java 对象和类

看一个简单的类:

public class Dog {

	String name;	// 实例变量
	String color;
	int age;
	
    // 构造器 public
	public Dog(String name, int age, String color) {	
		this.name = name;	// 参数名和实例变量名相同时,使用 this
        this.age = age;
        this.color=color;
	}
	
	public void run() {
		System.out.println(name + " is running...");
	}
	
	public int gerAge() {
		System.out.println("Age: " + age);
		return age;
	}
	
	public static void main(String[] args) {
		// 创建对象
		Dog myDog = new Dog("Tom", 2, "Brown");
        System.out.println(myDog.color);
		myDog.gerAge();
		myDog.run();
	}

}

这个类描述了小狗,属性包含:名字、颜色和年龄,类里面的函数称为方法。

类中包含了一个 static 的静态方法 public static void main(String[] args),不需要对象调用,可以自动执行。

this 关键字:

当实例变量和局部变量重名,JAVA平台会按照先局部变量、后实例变量的顺序寻找。

如果使用 this.name,则不会在方法(局部变量)中寻找变量name,而是直接去实例变量中去寻找。

当实例变量和局部变量名字不重复时,可以不使用 this,编译器会自动加上 this

2.1 构造器

一般构造函数 public 可加可不加。如果加上 public,就代表此类可以对外开放,其他的类可以继承它,外部也可以实例化该对象;如果不加 public,则默认的修饰词是protected,代表只对同包开放。

2.2 创建对象和访问实例

Dog tom = new Dog("Tom");   // 使用关键字 new 创建对象
tom.color                   // 访问属性
tome.run();                 // 访问方法

2.3 Java 包

import java.io.*	// 导入java_installation/java/io下的所有类

3. 数据与变量

3.1 基本数据类型

public class Data{
    public static void main(String[] args){
        int a = 65;
        short b = 0;
        float c = 2.5;
        int d = 100;    // decimal
        int e = 054;    // octal
        int f = 0x30;   // hex
        char ch = 'a';
        String str = "Hello";
        boolean full = false;
        
        byte a1 = (byte)a;  // 强制转换
        
        final double PI = 3.1459265;    // const
        
        // 可以查看特定类型数据的长度和范围
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Double.SIZE);
    }
}

Java 为每一个内置数据类型都提供了对应的包装类:Boolean, Byte, Short, Integer, Long, Character, Float, Double.

public class Test{
    public static void main(String[] args){
        Double x = 5.3;
		System.out.println(Math.floor(x));
    }
}

Java Math 类:

public class Test{
    public static void main(String[] args){
        System.out.println("PI = " + Math.PI);
        System.out.println("cos(PI/2) = " + Math.tan(Math.PI/4));
        System.out.println("random: " + Math.random());
        System.out.println("exp()")
    }
}

3.2 基本变量类型

  • 类变量:独立于方法之外的变量,用 static 修饰;
  • 实例变量:独立于方法之外的变量,不过没有 static 修饰;
  • 局部变量:类的方法中的变量。
public class Var{
    static int count = 0;  // 类变量
    String str = "Tom";    // 实例变量
    
    public void method(){
        int i = 0;         // 局部变量
    }
}

类变量属于静态变量,无论一个类有多少个对象,类变量都共用一个!


4. Java 修饰符

4.1 访问控制修饰符

Java 支持四种不同的访问权限:

default:在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

public : 对所有类可见。使用对象:类、接口、变量、方法

protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。

4.2 非访问修饰符

static

静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。

静态函数:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。

public class INstenceCOunter{
    private static int numInstences = 0;    // 静态变量
    
    prvate static void addInstence(){       // 静态函数
        numInstences++;
    }
}

注意:在静态方法中调用非静态方法时,编译器会报错(因为非静态方法只有实例化的对象能够调用,而静态方法执行的过程中未调用构造函数实例化对象,因此不允许调用!)

解决办法可以参考 博客 ,要么创建一个类的对象,通过对象来调用函数,要么将非静态方法声明中加上 static 改为静态方法,同时将变量声明为全局静态的。

final

被 final 修饰的实例变量必须显式指定初始值,之后不能再修改

public class Test{
    final double PI = 3.14159;   // 不能修改值
    
    // final 方法不能被子类重写
    public final void changeName(String name){
        this.name = name;
    }
}

5. 程序的逻辑结构

常见循环结构如下:

while (true){
    count--;
    if (count == 0)
        break;
}

for (int i=0; i<n; i++){
    count--;
}

String [] names = {"Tom", "Domy", "Sam"};
for (String name : names){
    System.out.print(name + " ");
}

常用的分支结构如下:

if (a == 1)
    return 1;
else if (a == 0)
    return -1;
else
    return 0;

switch (expression){
    case value1:
        pass;
    case value2:
        pass;
    default: 	// not match with any value
        pass;
}

6. String 字符串

6.1 字符串的存储

public class CharacterClass {

	public static void main(String[] args) {
		
		String str1 = "12345";	// 公共池
		String str2 = "12345";
		
		System.out.println(System.identityHashCode(str1));
		System.out.println(System.identityHashCode(str2));
		
		String str3 = new String("12345");	// 堆
		String str4 = new String("12345");
		
		System.out.println(System.identityHashCode(str3));
		System.out.println(System.identityHashCode(str4));
	}
}

函数 System.identityHashCode(str)可以打印出字符串 str 地址对应的哈希值

使用 String str = "xxxxx"; 声明的字符串存储在公共池里,存储字符串内容相同的字符串变量相当于引用;

使用 new String("xxxx"); 得到的字符串地址在堆内,每次 new 得到的对象地址不同;

110718392
110718392
231685785
114935352

6.2 字符串相关函数

长度 length()

// 长度 str.length()
String site = "blog.csdn.net";
int siteLength = site.length();
System.out.println("Length = " + siteLength);

格式化字符串 String.format(str, args)

String 类使用静态方法 format() 返回一个String 对象

// String.format(str, args)
String str = String.format("int a = %d, " + "float b = %f",  5, 5.2);
System.out.println(str);

字符索引查询 indexOf()

int pos1 = "abcdacd".indexOf('a');      // 0
int pos1 = "abcdacd".indexOf('k');      // -1
int pos2 = "abcdacd".lastIndexOf('a');  // 4

字符串分割 split()

String [] res1 = "abcdefghijklmnopqr".split("g");
String [] res2 = "abcdefghijklmnopqr".split("f|m");

子串 substring()

// public String substring(int beginIndex, int endIndex=-1)
String string = "this is text";
System.out.println(string.substring(2, 7));

比较函数 equals

填补一个大坑equals 比较的是内容是否相等、==比较的是引用的变量地址是否相等。

String str1 = new String("xxx");
String str2 = new String("xxx");
System.out.println(str1.equals(str2));

7. StringBuffer 和 StringBuilder 类

7.1 特点

StrngBuilder 和 StringBuffer 类的对象支持多次的 增删改查,而且并且不产生新的未使用对象!

  • StringBuilder 的方法不是线程安全的,但速度高(不能同步访问)。
  • 由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

7.2 StringBuilder 和 StringBuffer 的使用

常用函数的语法如下(StringBuilder 和 StringBuffer 的使用方法几乎相同):

StringBuilder sb = new StringBuilder(int capacity);	   // 创建对象

// 与 string 相同的函数
public int length()
public StringBuilder(int capacity)
public String substring(int beginIndex, int endIndex)

// 修改内容
public StringBuilder append(char[] str)            // 追加字符串
public StringBuilder insert(int index, char[] str) // 在 index 插入 str
public StringBuilder delete(int start, int end)    // 删除 [start, end)
public StringBuilder replace(int start, int end, String str) // 将 [start, end) 的内容用 str 替换

public synchronized StringBuffer reverse()         // StringBuffer reverse

举个例子:

public class StringB {

	public static void main(String[] args) {
		
		StringBuilder sb = new StringBuilder(10);
		sb.append("Runoob..");
		System.out.println(sb);
		
		sb.append("!");
		System.out.println(sb);
		
		sb.insert(8, "Java");
		System.out.println(sb);
		
		sb.delete(5, 8);
		System.out.println(sb);
	}
}

输出的结果为,具体可以参考 菜鸟教程

Runoob..
Runoob..!
Runoob..Java!
RunooJava!

8. 数组的使用

声明与创建:

int[] myList;          // declare
myList = new int[10];  // 创建

int arraySize = 10;
double myList = new double[arraySize];

int[][] a = new int[3][4];	// 多维数组
int[] a = {0, 1, ..., n};   // 初始化

数组的访问与修改:

import java.lang.reflect.Array;

public class ArrayTest {
    
    // reveerse array element
	public static int[] reverseArray(int[] list) {
		int[] res = new int[list.length];
		for (int i=0; i<list.length; i++) {
			res[i] = list[list.length-1 - i];
		}
		return res;
	}
	
	public static void main(String[] args) {
		int size = 10;
		int[] array = new int[size];
		
		for (int i=0; i<array.length; i++) {
			array[i] = i*i;
		}
        
		int[] reversedArray = reverseArray(array);
		for (int elem : reversedArray) {
			System.out.print(elem + " ");
		}
	}
}
// 81 64 49 36 25 16 9 4 1 0 

可以使用 Arrays类的函数来对数组操作:

public static void sort(Object[] a)    // 排序
public static int binarySearch(Object[] a, Object key)  // 在有序数组中折半查找

举个例子:

import java.util.Arrays;

public class ArrayTest {

	public static void main(String[] args) {
		int size = 5;
		double[] array = new double[size];
		
		for (int i=0; i<array.length; i++) {
			array[i] = Math.random();
		}
		Arrays.sort(array);
		for (double elem : array) {
			System.out.println(elem);
		}
	}
}

9. Java 方法

9.1 方法的定义与调用

一个方法包含了 修饰符返回值类型方法名参数方法体构成

在不创建类对象的情况下,主函数可以调用静态方法:

public class MethodTest {
	
	public static int max(int a, int b) {
		return a > b ? a : b;
	}
	public static void main(String[] args) {
		int a = 2;
		int b = 5;
		System.out.println(max(a, b));
	}
}

9.2 可变参数

可变参数的声明方式为:

typeName... parameterName

举个例子:

public class Test{
    public static void main(String[] args){
        System.out.println(sum(1, 2, 3, 4, 5));  // 15.0
    }
    
    public static double sum(double... list){
        double res = 0;
        for (double elem : list){
            res += elem;
        }
        return res;
    }
}

此处传入的参数有很多个,可以像数组一样来访问传入的参数。


10. 时间和日期

10.1 查看时间

java.util 包提供了 Date 类来封装当前的日期和时间,可以 new 一个 Date 对象:

import java.util.Date;

public class Test{
    public static void main(String[] args){
        Date date = new Date();    // 初始化对象
        System.out.println(date.toString());
    }
}

10.2 格式化输出时间

import java.util.Date;
import java.text.SimpleDateFormat;

public class Test{
    pblic static void main(String[] args){
        // 创建 Date 对象
        Date currTime = new Date();
        // 设置格式
        SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss yyyy/MM/dd E");
        // 格式化输出
        System.out.println("Current time: " + ft.format(currentTime));
    }
}

10.3 测量时间

Thread.sleep(1000) 休眠 1000ms

System.currentTimeMillis() 获取毫秒数

import java.util.Date;

try {
    // 获取从1970年1月1号0时0分0秒至今的毫秒数
    long start = System.currentTimeMillis();	
    System.out.println(new Date().toString());

    // 休眠 3 s
    Thread.sleep(3000);

    System.out.println(new Date().toString());
    long end = System.currentTimeMillis();

    long diff = start - end;
    System.out.println(diff + " msec");
} catch (Exception e) {
    System.out.println("Got an exception!");
}

10.4 Calendar 类

import java.util.Calendar;

public class Test1 {

	public static void main(String[] args) {
		Calendar c1 = Calendar.getInstance();
		System.out.println(c1.getTime());
		System.out.println(c1.get(Calendar.YEAR));
		System.out.println(c1.get(Calendar.MONTH));
		System.out.println(c1.get(Calendar.DATE));
	}
}

11. 输入与输出

11.1 Scanner 类

Java 提供了 Scannner 类,可以设置参数来从键盘读取数据,创建Scanner对象如下:

import java.util.Scanner;

Scanner scan = new Scanner(System.in); // 参数 System.in 代表读取键盘的输入

11.2 读取字符串

输入字符串的方式有两种:

next()

  • 一定要读取到有效字符后才可以结束输入
  • 输入一行时,以空格分隔字符串,因此不能得到带有空格的字符串;

nextLine()

  • 输入一行,以换行符结束,能读取有空格的字符串
  • 可以读取空白内容

举个例子:(输入为 “hello world”)

import java.util.Scanner;

public class Test{
    public static void main(String[] args){
        
        Scanner sc1 = new Scanner(System.in);   
        System.out.println(sc1.next());         // hello
        
        Scanner sc2 = new Scanner(System.in);
        System.out.println(sc2.nextLine());     // hello world
        
    }
}

11.3 读取数字

下面的程序对输入的所有数字求和,当输入不是 double 类型时(如字符串),程序会终止

import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		double sum = 0;
		while (sc.hasNextDouble()) {
			sum += sc.nextDouble();
		}
		sc.close();
		System.out.println("Sum: " + sum);
	}
}

12. 异常捕获

使用 try-catch 来捕获 异常

try{
    double c = 3/0;
} catch (Exception e){
    System.out.println("Got an error: " + e); // 打印错误
} finally{
    System.out.println("This statement is excuted!");
}

可以有多个 catch 来捕获不同类型的错误;不论是否存在异常,finall关键字中的语句都会被执行。

输出结果为:

Got an error: java.lang.ArithmeticException: / by zero
This statement is excuted! 

13. data structure

Java 提供了一系列的存储数据结构和相应的算法,各种容器由 Collections继承而来,算法可以通过 Collections类来调用;容器的创建方法如下:

import java.util.ContainerName;    // 引入容器类
ContainerName<E> objectName =new ContainerName<E>();  // 初始化

13.1 ArrayList

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制;

package dataStructure;

import java.util.ArrayList;
import java.util.Collections;

public class dataStructure {

	public static void main(String[] args) {

		ArrayList<Integer> myList = new ArrayList<Integer>();
		myList.add(1);
		myList.add(5);
		myList.add(2);
		myList.add(6);
		myList.add(4);
		myList.remove(0);
		for (Integer i : myList) {
			System.out.print(i + " ");
		}
        
		System.out.println();
		Collections.sort(myList);
//		Collections.reverse(myList);
		for (Integer i : myList) {
			System.out.print(i + " ");
		}
	}
}

13.2 Stack

Stack 常用的方法有:boolean empty(), E push(), E pop(), E peek()

package dataStructure;

import java.util.Stack;

public class dataStructure {

	public static void main(String[] args) {
		Stack<Integer> s = new Stack<Integer>();
		s.push(1);              // 压栈
		s.push(2);
		s.push(3);
		s.push(4);
		s.push(5);
		
		Integer a = s.peek();   // 访问栈顶
		System.out.println(a);
		
		Integer sum = 0;
		while(!s.empty()) {     // 判空
			sum += s.pop();     // 弹栈
		}
		System.out.println(sum);
	}
}

除此之外,Java 还有 Vector, LinkList, Queue, Dictionary等常用容器,可以通过查看手册或查看源码来学习使用!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值