Java学习记录(基础)——易忽略点

1、Eclipse常用快捷键 

alt+shift+r 批量修改
ctrl+shift+f  代码格式化
ctrl+shift+o import 类 
去掉未使用的类 等等
ctrl+shift+c 快速注释
ctrl+shift+x 小写转换为大写
ctrl+shift+y 大写转换为小写
ctrl+1 快速解决办法提示
alt+shift+s 默认方法快速生成
alt+shift+j javadoc文档快速生成

2、控制台输入

从控制台输入数据,需要用到Scanner类

注意:使用Scanner类,需要import包:

import java.util.Scanner;

使用流程:

// 首先,创建Scanner对象
Scanner scanner = new Scanner(System.in);
// 然后,利用Scanner对象获取相应的数据,如:↓ ↓ ↓ 
int a = scanner.nextInt();    // 获取控制体输入的整数

示例:

/* 
 * 使用Scanner读取整数
 */
import java.util.Scanner;

public class ScannerTest{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        System.out.println("从控制台输入的第一个整数:" + a);
        int b = scanner.nextInt();
        System.out.println("从控制台输入的第二个整数:" + b);
    }
}
/* 
 * 使用Scanner读取浮点数
 */
import java.util.Scanner;

public class ScannerTest{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        float a = scanner.nextFloat();
        System.out.println("从控制台输入的是浮点数:" + a);
    }
}
/* 
 * 使用Scanner读取字符串
 */
import java.util.Scanner;

public class ScannerTest{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        String a = scanner.nextLine();
        System.out.println("从控制台输入的是字符串:" + a);
    }
}
/* 
 * 使用Scanner读取整数后接着读取字符串
 */
import java.util.Scanner;

public class ScannerTest{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        System.out.println("从控制台输入的整数是:" + a);
        String str = scanner.nextLine();
        System.out.println("从控制台输入的字符串是:" + str);
    }
}

3、数组排序算法:直接选择法和冒泡法

    (1)、直接选择法

        直接选择法排序的思路是:

        把第一个元素和后面所有的元素进行比较,只要比第一个元素小的,就和第一个元素互换位置 ,以此找到最小的元素
        比较完后,第一位就是最小的 

        然后再把第二个元素和后面所有的元素进行比较,只要比第二个元素小的,就和第二个元素 互换位置,以此找到第二小的元素
        比较完后,第二位就是第二小的 

        以此类推

        éæ©æ³æåº

        

public class SortTest {
    public static void main(String[] args) {
		SortTest test = new SortTest();
		int[] a = new int[]{18,62,68,82,65,9};
		a = test.sort(a);
		for (int i : a) {
			System.out.print(i + "\t");
		}
	}
	
	public int[] sort(int[] a) {
		// 从第一个元素开始依次比较,将这些元素暂且称为原点元素
		for (int i = 0; i < a.length-1; i++) {
			// 从原点元素的下一个元素开始,依次与原点元素进行比较,如果有元素比原点元素小,那么与原点元素互换
			for (int j = i+1; j < a.length; j++) {
				if (a[j] < a[i]) {
					int temp = a[i];
					a[i] = a[j];
					a[j] = temp;
				}
			}
		}
		return a;
	}
}

  输出结果为:

    (2)、冒泡法

        冒泡法排序的思路是:

        第一步:从第一个元素开始,把相邻两个元素进行比较,如果发现前者比后者大,就把大的数据交换在后面,循环比较完毕后,最后一位就是最大的 

        第二步: 再来一次,只不过不用比较最后一位 

        以此类推

       å泡æ³æåº

public class SortTest {
    public static void main(String[] args) {
		SortTest test = new SortTest();
		int[] a = new int[]{18,62,68,82,65,9};
		a = test.sort(a);
		for (int i : a) {
			System.out.print(i + "\t");
		}
	}
	
	public int[] sort(int[] a) {
		// 从1开始,有n个元素,就要比较n-1趟,每比较一趟,确认一个最大/次大数
		for (int i = 1; i < a.length; i++) {
			// 从第一个元素开始,直到(总数-减去已确认最大/次大数的数量)的前一个元素,与后一个元素进行比较,大的放后边
			for (int j = 0; j < a.length-i; j++) {
				if (a[j] > a[j+1]) {
					int temp = a[j];
					a[j] = a[j+1];
					a[j+1] = temp;	
				}
			}
		}
		return a;
	}
}

输出结果为:

4、针对数组的工具类——Arrays

注意:使用Arrays类,需要import包:

import java.util.Arrays;

Arrays工具类的方法:

方法名 功能
copyOfRange 数组复制
toString() 转换为字符串
sort 排序
binarySearch 搜索
equals 判断是否相同
fill 填充
import java.util.Arrays;

public class ArraysTest {

	public static void main(String[] args) {
		int a[] = new int[] { 18, 62, 68, 82, 65, 9 };

		System.out.print("原数组为:");
		for (int i : a) {
			System.out.print(i + "  ");
		}
		System.out.println();

		// *********************复制数组**********************
		System.out.println("*********************复制数组**********************");
		// copyOfRange(int[] original, int from, int to)
		// 第一个参数表示源数组
		// 第二个参数表示开始位置(取得到)
		// 第三个参数表示结束位置(取不到)
		int[] b = Arrays.copyOfRange(a, 0, 3);

		System.out.print("复制的数组:");
		for (int i = 0; i < b.length; i++) {
			System.out.print(b[i] + " ");
		}
		System.out.println();

		// *********************转换为字符串**********************
		System.out.println("*********************转换为字符串**********************");
		// toString(int[] a)
		// 参数a代表源数组
		String str = Arrays.toString(a);
		System.out.println("转换为字符串后的形式:" + str);

		// *********************排序**********************
		System.out.println("*********************排序**********************");
		// sort(int[] a)
		// 参数a代表源数组
		System.out.println("排序前:");
		System.out.println(Arrays.toString(a));

		Arrays.sort(a);
		System.out.println("排序后:");
		System.out.println(Arrays.toString(a));

		// *********************搜索元素的位置**********************
		System.out.println("*********************搜索元素的位置**********************");
		// binarySearch(int[] a, int key)
		// 参数a代表源数组
		// 参数key代表要查找的元素
		// 要注意的是:在查找前需要先对数组进行排序
		Arrays.sort(a);
		System.out.println("62的位置在:" + Arrays.binarySearch(a, 62));

		// *********************判断是否相同**********************
		System.out.println("*********************判断是否相同**********************");
		// equals(int[] a,int[] b)
		// 参数a和b分别代表要进行比较的两个数组
		int x[] = new int[] { 18, 62, 68, 82, 65, 9 };
		int y[] = new int[] { 18, 62, 68, 82, 65, 8 };
		System.out.println("数组x为:" + Arrays.toString(x));
		System.out.println("数组y为:" + Arrays.toString(y));
		System.out.println("数组x和数组y进行比较的结果是:" + Arrays.equals(x, y));

		// *********************填充**********************
		System.out.println("*********************填充**********************");
		// fill(int[] a,int val)
		// 参数a代表源数组
		// 参数val代表要填充的值
		int c[] = new int[10];

		System.out.println("填充前的c数组为:" + Arrays.toString(c));
		Arrays.fill(c, 5);
		System.out.println("填充后的c数组为:" + Arrays.toString(c));

	}

}

输出结果为:

5、属性初始化

对象属性初始化的方法有3种:

    (1)、声明该属性的时候初始化 
    (2)、构造方法中初始化
    (3)、初始化块

public class AttrInitTest {

	public String name = "name属性"; // 声明该属性的时候初始化
	protected int hp;
	private int maxHP;

	{
		maxHP = 200; // 初始化块
	}

	public AttrInitTest() {
		hp = 100; // 构造方法中初始化

	}

	public static void main(String[] args) {
		AttrInitTest test = new AttrInitTest();
		System.out.println(test.name + "\t" + test.maxHP + "\t" + test.hp);

	}

}

输出结果为:

类属性初始化的方法有2种:

    (1)、声明该属性的时候初始化
    (2)、静态初始化块

public class AttrInitTest {

	public String name = "name属性"; // 声明该属性的时候初始化
	protected int hp;
	private int maxHP;

	public static int itemCapacity=8; //声明的时候 初始化

    public AttrInitTest(){
         
    }
     
    public static void main(String[] args) {
        System.out.println(AttrInitTest.itemCapacity);
    }

}

输出结果:

public class AttrInitTest {

	public String name;
	protected float hp;
	float maxHP;

	public static int itemCapacity; // 声明类属性

	static {
		itemCapacity = 6;// 静态初始化块 初始化
	}

	public AttrInitTest() {

	}

	public static void main(String[] args) {
		System.out.println(AttrInitTest.itemCapacity);
	}

}

输出结果:

【声明属性时初始化】、【构造方法中初始化】、【初始化块中初始化】 这3中初始化的顺序:

声明时初始化 → 初始化块中初始化 → 构造方法中初始化

6、单例模式

单例模式又叫做 Singleton模式,指的是 : 一个类,在一个JVM里,只有一个实例存在。也就是只能被实例化一次

打个比方: 王者峡谷中的暗影主宰只有一个,所以主宰这个类只能被实例化一次

原理:【

单例模式的类只能被实例化一次,那么,就不能通过外部new的方式得到新的实例,

所以,我们需要将构造方法私有化;

但是,毕竟还要实例化一次的,那么,我们在类内声明一个静态属性,

使得这个静态属性指向实例化对象;

接下来,毕竟类设计出来就是要用的,那么,我们需要一个方法来将这个实例化对象,也就是已经指向这个实例的静态属性返回,

即返回实例;

综上,我们就总结出了单例模式的三元素:

【构造方法私有化、 静态属性指向实例、类方法 getInstance,返回静态属性,即唯一实例】

下面,来看以下代码示例:

饿汉式单例模式:

class Zhuzai{
	
	// 私有化构造方法使得该类无法在外部通过new 进行实例化
	private Zhuzai() {
		
	}
	
	// 准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
	private static Zhuzai zhuzai = new Zhuzai();
	
	// public static 方法,提供给调用者获取类的唯一实例对象
	public static Zhuzai getInstnce() {
		return zhuzai;
	}
	
}

public class SingletonTest {

	public static void main(String[] args) {
		Zhuzai zhuzai1 = Zhuzai.getInstnce();	// 新建一个主宰对象
		Zhuzai zhuzai2 = Zhuzai.getInstnce();	// 再次新建一个主宰对象
		// 分别输出两个主宰对象的地址
		System.out.println(zhuzai1);
		System.out.println(zhuzai2);
	}
	
}

输出结果:

可以很明显的看出,这两个主宰对象其实是同一个,他们的地址都是一样的。

懒汉式单例模式:

class Zhuzai{
	
	// 私有化构造方法使得该类无法在外部通过new 进行实例化
	private Zhuzai() {
		
	}
	
	//准备一个类属性,用于指向一个实例化对象,但是暂时指向null
	private static Zhuzai zhuzai;
	
	// public static 方法,提供给调用者获取类的唯一实例对象
	public static Zhuzai getInstnce() {
		//第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
        if(null == zhuzai){
        	zhuzai = new Zhuzai();
        }
        //返回 instance指向的对象
        return zhuzai;
	}
	
}

public class SingletonTest {

	public static void main(String[] args) {
		Zhuzai zhuzai1 = Zhuzai.getInstnce();	// 新建一个主宰对象
		Zhuzai zhuzai2 = Zhuzai.getInstnce();	// 再次新建一个主宰对象
		// 分别输出两个主宰对象的地址
		System.out.println(zhuzai1);
		System.out.println(zhuzai2);
	}
	
}

输出结果:

可以很明显的看出,这两个主宰对象其实是同一个,他们的地址都是一样的。

饿汉式和懒汉式的区别及应用场景:

    饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载。
        如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。
    懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量。
        使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。


    看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式。

注意:【这个是面试的时候经常会考的点,面试题通常的问法是: ↓ ↓ ↓ 】

什么是单例模式?


回答的时候,要答到三元素
1. 构造方法私有化
2. 静态属性指向实例
3. public static的 getInstance方法,返回第二步的静态属性

7、Java中的方法隐藏

隐藏与重写类似;

方法的      重写,是子类覆盖父类的对象方法 ;
而方法的  隐藏,是子类覆盖父类的类方法

class Father{
	public static void method() {
		System.out.println("这是父类的类方法!");
	}
}


public class MethodHiddenTest extends Father {

	public static void method() {
		System.out.println("这是子类的类方法!");
	}
	
	public static void main(String[] args) {
		Father.method();	// 调用父类的method方法
		MethodHiddenTest.method();	// 调用子类的method方法
	}
	
}

输出结果:

子类的method方法将父类的method方法隐藏掉了,调用时直接调用的是子类的method方法。

8、Java 的修饰符 final

fianl 修饰类,表示该类为最终类,不能再被继承;

final 修饰方法,表示在其子类中,该方法不能被重写;

final 修饰基本类型变量,表示该变量只有一次赋值机会 ;

final 修饰引用,表示该引用只有1次指向对象的机会,但是该对象的属性值依旧可以被修改。

9、接口的默认方法

默认方法是JDK8新特性,指的是接口也可以提供具体方法了,而不像以前,只能提供抽象方法。

默认方法需要声明为default 

interface TestInterface{
	default void defaultMethod() {
		System.out.println("这是默认方法!");
	}
}

public class DefaultMethodTest implements TestInterface {

	public static void main(String[] args) {
		TestInterface test = new DefaultMethodTest();
		test.defaultMethod();
	}
	
}

输出结果:

10、Java Math 类常用数学方法记录

方法名 功能
round 四舍五入
random 得到一个0-1之间的随机浮点数(取不到1)
random()*10 得到一个0-10之间的随机整数 (取不到10)
sqrt 开方
pow(2,4) 2的4次方

11、字符串的格式化输出

printf 和 format 可以达到格式化输出字符串的效果,其作用效果一样,源码层次上是 printf 中直接调用了 format ;

public class FormatStringTest {

	public static void main(String[] args) {
		String name = "盖伦";
		int kill = 8;
		String title = "超神";

		String sentenceFormat = "%s 在进行了连续 %d 次击杀后,获得了 %s 的称号%n";
		// 使用printf格式化输出
		System.out.printf(sentenceFormat, name, kill, title);
		// 使用format格式化输出
		System.out.format(sentenceFormat, name, kill, title);
	}

}
格式 含义
%s 字符串
%d 数字
%n 换行

12、字符串内容比较(忽略大小写)

equalsIgnoreCase(String anotherString)

13、StringBuffer

StringBuffer是可变长的字符串;

StringBuffer 的常用方法:

方法名 功能
append("new String") 在原有字符串后面追加
delete(410) 删除4-10之间的字符(包括4,不包括10)
insert(4"there ") 在4这个位置插入 there
reverse() 反转
length() 内容长度
capacity() 总空间

为什么StringBuffer可以变长?

和String内部是一个字符数组一样,StringBuffer也维护了一个字符数组。 但是,这个字符数组,留有冗余长度。

比如说new StringBuffer("the"),其内部的字符数组的长度,是16,而不是3,这样调用插入和追加,在现成的数组的基础上就可以完成了。
如果追加的长度超过了16,就会分配一个新的数组,长度比原来多一些,把原来的数据复制到新的数组中,看上去 数组长度就变长了 .
length: “the”的长度 3
capacity: 分配的总空间 16

StringBuffer 和 String 的性能比较:

ç»ä¹ -StringBufferæ§è½

14、日期类 Date

注意:使用日期类 Date ,需要导入相应的包:

import java.util.Date;

在计算机里,日期类型会用一个数字来代替,其代表的是距离1970年1月1日8时0分0秒过去了多少毫秒。

0就代表Java中的时间原点,其对应的日期是1970年1月1日 8点0分0秒 。

所有的日期,都是以为这个0点为基准,每过一毫秒,就+1。

创建日期对象:

import java.util.Date;

public class DateTest {

	public static void main(String[] args) {
		Date test = new Date();
		System.out.println(test);
	}
	
}

输出结果:

Date 对象的常用方法有:

方法名 功能
getTime() 得到一个long型的整数
这个整数代表 从1970.1.1 08:00:00:000 开始 每经历一毫秒,增加1
currentTimeMillis() 当前日期的毫秒数

15、日期格式化

要格式化日期,需要用到 SimpleDateFormat 日期格式化类

注意,需要导入相应的包:

import java.text.SimpleDateFormat;

格式化的格式:

格式 含义

y

代表年
M 代表月
d 代表日
H 代表24进制的小时
h 代表12进制的小时
m 代表分钟
s 代表秒
S 代表毫秒

转化的方法如下:

方法名 功能
format 日期转字符串
parse 字符串转日期
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatTest {

	public static void main(String[] args) {
		// y 代表年
		// M 代表月
		// d 代表日
		// H 代表24进制的小时
		// h 代表12进制的小时
		// m 代表分钟
		// s 代表秒
		// S 代表毫秒
		
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		Date d = new Date();
		String str = sdf.format(d);
		System.out.println("当前时间通过 yyyy-MM-dd HH:mm:ss SSS 格式化后的输出: " + str);

		
		
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		String str1 = "2016/1/5 12:12:12";
		try {
			Date d1 = sdf1.parse(str1);
			System.out.printf("字符串 %s 通过格式  yyyy/MM/dd HH:mm:ss %n转换为日期对象: %s", str, d.toString());
		} catch (ParseException e) {
			e.printStackTrace();
		}

	}

}

输出结果:

16、日历类 Calendar

注意:要使用Calendar 包,需要导入相应的包:

import java.util.Calendar;

Calendar类即日历类,常用于进行“翻日历”,比如下个月的今天是多久。

Calendar与Date进行转换:

采用单例模式获取日历对象Calendar.getInstance();

import java.util.Calendar;
import java.util.Date;

public class CalendarTest {

	public static void main(String[] args) {
        //采用单例模式获取日历对象Calendar.getInstance();
        Calendar c = Calendar.getInstance();
          
        //通过日历对象得到日期对象
        Date d = c.getTime();
        System.out.println(d);
  
        Date d2 = new Date(0);
        c.setTime(d2); //把这个日历,调成日期 : 1970.1.1 08:00:00
        System.out.println(c.getTime());
    }
	
}

输出结果:

Calendar 类翻日历的方法:

方法名 功能
add(int file, int amount) 在原日期上增加年/月/日(field 代表是年还是月还是日等)
set 直接设置年/月/日
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarTest {

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");

	public static void main(String[] args) {
		Calendar c = Calendar.getInstance();
		Date now = c.getTime();
		// 当前日期
		System.out.println("当前日期:\t\t" + format(c.getTime()));

		// 下个月的今天
		c.setTime(now);
		c.add(Calendar.MONTH, 1);
		System.out.println("下个月的今天:\t" + format(c.getTime()));

		// 去年的今天
		c.setTime(now);
		c.add(Calendar.YEAR, -1);
		System.out.println("去年的今天:\t\t" + format(c.getTime()));

		// 上个月的第三天
		c.setTime(now);
		c.add(Calendar.MONTH, -1);
		c.set(Calendar.DATE, 3);
		System.out.println("上个月的第三天:\t" + format(c.getTime()));

	}

	private static String format(Date time) {
		return sdf.format(time);
	}

}

输出结果:

17、基本数据类型的长度及范围

类型 缺省值 长度 范围
byte 0 8位 -128~127
short 0 16位 -32,768~32,767
int 0 32位 -2,147,483,648~2,147,483,647
long 0 64位 -9,223,372,036,854,775,808~9,223,372,036,854,775,807
float 0.0 32位 3.4E-038~3.4E+038
double 0.0 64位 1.7E-308~1.7E+308
char 16位 一个字符
boolean false 1位 true/false

猜你喜欢

转载自blog.csdn.net/qq_37164975/article/details/82555546
今日推荐