1.java基本概念
1.java特性和优势
———基于c语言实现,采用面向对象的程序设计,支持网络编程、分布式编程、多线程开发,具有可移植性、动态性、高性能、安全性以及健壮性的特征;
- 简单性:基于c语言,c++语法简化版,去除了一些内容:没有头文件,没有指针运算等;
- 面向对象:是一种程序设计技术,一切皆对象,包括属性方法,涉及封装、继承、多态;
- 可移植:跨平台,一次编写到处运行,java代码编译成class文件,通过jvm(本身没有语言特性)去执行
- 分布式:适用于网络的分布式环境,能够处理tcp,ip协议,支持远程方法调用,通过网络去调用方法
- 动态性:通过反射机制去实现
- 多线程:支持多线程技术,同一个进程有不同的执行路径
- 高性能:及时编译、jvm技术的提高
- 安全性:强类型语言、 Java可以很容易构建防病毒,防篡改的系统
- 健壮的:异常处理机制
2.Java三大版本
- JavaSE:标准版,包括桌面程序,控制台开发
- JavaVM: 嵌入式开发
- JavaEE:E企业级开发,包括web端,服务器开发
3.jvm,jre,jdk
- jdk:开发工具(java语言、tools、api等常用的有:java,javac,jar等) +jre+jvm
- jre:java运行环境+jvm
- jvm:java虚拟机 运行.class文件,满足了java可移植性
4.编译型语言,解释性语言
- 编译型:将程序编译成计算机能处理的语言 :操作,c,c++等
- 解释性:边执行边解释 网页、js、java;
5.程序运行机制
- 通过编译器,先将程序文件,预编译成.class的字节码文件;
- 通过解释器将字节码文件解释成可执行的程序让操作系统去执行;
2.数据相关
java是强类型语言:变量使用要严格符合规定,所有变量都必须先定义后才能使用
1.数据类型
1.基本数据类型表示
public class BaseType {
public static void main(String[] args) {
/*
* 重要:通过查看对应包装类的属性属性值,查看可表示数值的范围;
*Integer.MAX_VALUE;
* Integer.MIN_VALUE;
* */
//基本数据类型8个
//整数
int num1 = 10;//常用,10亿级别
byte num2 = 20;
short num3 = 30;
long num4 = 30L;//long类型要在数字后面加个L
//小数
float num5 = 11.1F; //float类型要在数字后面加个F
double num6 = 12.1;
//字符
char name = 'd';
//字符串与字符区别
// String namea = "aaaa";
//布尔值:
boolean bool = true;
}
}
2.基本数据类型扩展
- 整数扩展:进制表示: 二进制:0b 八进制: 0 十六进制:0x
- 小数扩展:浮点数,范围有限,表示大数用BigDecimal;存在舍入误差,结果离散问题 避免使用浮点数进行比较
- 字符扩展:所有字符本质上为数字
- 布尔值扩展:代码精简易读
public class BaseTypeExpand {
public static void main(String[] args) {
/*
* 1.整数扩展:
* 不同进制表示方式 二进制0b 十进制 八进制0 十六进制0x
* */
System.out.println("=======1.整数扩展->进制============");
int i = 10;
int i1 = 0b10;
int i2 = 010;
int i3 = 0x10;//十六进制 0x 0~9 A~F
System.out.println(i);
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
/*
* 2.浮点数拓展 银行业务怎么表示?
* float 表示值有限、结果是离散的、舍入误差 接近但不等于
* double
* 注意:避免使用浮点数进行比较
* BigDecimal 数学工具类,表示大数类
* */
System.out.println("=======2.浮点数拓展,结果离散、舍入误差、避免使用浮点数比较==========");
float f = 0.1f;
double d = 1.0/10;
System.out.println(f==d);//false
float d1 = 231234235254242f;
float d2 = d1+1;
System.out.println(d1==d2);//true 数据超长了
/*
* 3.字符扩展 :
* 所有的字符本质上为数字
* 对应Unicode编码: a->97 A->64 占2个字节 最大表示65536 excel
* 范围: U0000 UFFFF
* */
System.out.println("=======3.字符扩展,所有字符本质上为数字、转义字符=========");
char c1 = 'a';
char c2 = '中';
char c3 = '\u0061'; //a的Unicode编码表示,16进制表示
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
//强制转换->所有的字符本质上为数字
System.out.println((int) c1);
System.out.println((int) c2);
/*
* 转义字符
* \n 换行
* \t 制表符 tab长度
* */
System.out.println("hello\tword");
System.out.println("hello\n");
System.out.println("=======4.字符串扩展,内存分析==========");
//4.字符串扩展 对象,内存分析
String sa = new String("hello world");
String sb = new String("hello world");
System.out.println(sa==sb);
String sc = "hello world";
String sd = "hello world";
System.out.println(sc==sd);
System.out.println("======5.布尔值扩展、代码精简易读======");
//5.布尔值扩展
boolean flag = true;
if (flag){} //代码要精简易读
}
}
3.数据类型转换
- 容量排序:byte,short,char->int->long->float->double
- 强制类型转换:高->低 注意内存溢出和精度损失
- 自动类型转换:低->高
public class TypeConversion {
public static void main(String[] args) {
/*
* 1.强制类型转换 高->低
* 自动转换 低->高
* 注意:小数的优先级大于整数
* byte,short,char->int->long->float->double
* */
System.out.println("===1.强制转换,强制类型转换注意内存溢出、精度损失=====");
int i = 128;
double c = i;
//强制类型转换方法: (类型)变量名
System.out.println(i);
System.out.println((byte) i);//注意内存溢出
System.out.println(c);
/*
* 注意点:
* 1.不能对boolean类型进行转换
* 2.不能把对象类型转换为不相干类型
* 3.把高容量转换为低容量时候,强制转换
* 4.强制类型转换的时候可能存在内存溢出、精度问题
* */
//内存溢出问题 低->高
byte b = (byte) i;
System.out.println(b);
//精度损失问题 高->低
System.out.println((int) 23.7);
System.out.println((int) -45.67f);
//字符与数字之间转换
char d = 'a';
int e = d+1;
System.out.println(e);
System.out.println((char) e);
/*
* 常见问题:
* 操作数较大的时候,主要溢出问题
* JDK7之后特性,数字之间可以用下划线分割
* */
int money = 10_0000_0000;
int year = 20;
int sal = money*year;
long sal1 = money*(long)year;//提前进行转换
System.out.println(sal);//计算的时候内存溢出
System.out.println((long) sal);//默认是int,转换之前已经存在问题
System.out.println(sal1);//提前转换,防止溢出
//L 使用大写L表示long,F表示是float 注意规范
}
}
2.变量
- 按作用域划分: 实例变量(成员变量)、静态变量(类变量)、局部变量(方法中)
- 变量命名规范:见名知义、驼峰命名(变量、方法:首字母小写;类:首字母大写)、常量(大写字母+下划线)
public class Variable {
//1.类变量 static
static double salary = 2000;
//修饰符,不存在先后顺序
//4.常量
static final double PI=3.14;
//属性:变量
/*
* 2.实例对象:从属于对象
* 布尔值:默认值为null
* 基本类型初始值为:0,其余默认值都为null
* */
String name;
int age;
//静态代码块
static {
}
//main方法
public static void main(String[] args) {
//3.局部变量:必须声明和初始化
int i = 0;
System.out.println(i);
//使用实例变量
Variable var = new Variable();
System.out.println(var.name);
//使用类变量 加static
System.out.println(salary);
//使用常量
System.out.println(PI);
}
//其他方法
public void add(int i){
//3.局部变量
System.out.println(i);
}
}
3.运算符
运算符 | 包括 |
---|---|
算法运算符 | +, -, *, /, %, ++, – |
赋值运算符 | = |
关系运算符 | >, <, >=, <=, ==, !=, instanceof |
逻辑运算符 | &&,||,! |
位运算符 | &, |, ^, ~, >>, <<, >>> |
条件运算符 | ?: |
扩展运算符 | +=,-=,*=,/= |
1.位运算
public static void main(String[] args) {
// 与&& || !
boolean a = true;
boolean b = true;
//短路运算 **
int c = 5;
boolean d = (c<4)&&(c++<4); //c<4为false则不会进行c++的运算
System.out.println(d);
System.out.println(c);
/**
* 位运算:效率高
* 与 & 或| 非 ~
* 异或^:相同为0,不同为1
* << 数字*2 >> 数字/2
* 例子:
* 0000 0001 1
* 0000 0010 2
* 0000 0100 4
* 0000 1000 8
*/
System.out.println(8>>3);//2的3次方
System.out.println(2<<3);
}
}
2.Math常用方法
public class MathOperator {
public static void main(String[] args) {
//幂运算 2^3 工具类
System.out.println(Math.max(10.2,11));//比较两个数大小
System.out.println(Math.sqrt(9));//平方根
double res = Math.pow(3,2);
System.out.println(res);//3的2次方
System.out.println(Math.abs(-1));//绝对值
System.out.println(Math.exp(0));//e^0
}
}
3.short,byte,char输出自动转成int
public class Operator {
public static void main(String[] args) {
//类型向上
//short,byte,char类型会自动转成 -> int
long a = 121321314141414L;
int b = 123;
short c = 10;
byte d = 8;
char e = '2';
System.out.println(a+b+c+d);//long
System.out.println(b+c+d);//int
System.out.println(c+d);//int
System.out.println(d+e);
}
}
4.字符串连接-计算优先级
public class StringConcat {
public static void main(String[] args) {
int a = 1;
int b = 2;
//字符串连接
System.out.println(""+a+b);//12
System.out.println(a+b+"");//3
}
}
5.++i和i++
++i:先自增,再赋值; i++:先赋值再自增;
public class IncrementOperator {
public static void main(String[] args) {
//自增
int num1 = 3;
int num2 = num1++;//执行到这一步,先把num1赋值给num2,再自增
//num1 = num1+1;
System.out.println(num1);//3
//num1 = num1+1;
int num3 = ++num1;//执行到这一步,先把num1自增1,再赋值给num3
System.out.println(num1);//5
System.out.println(num2);//3
System.out.println(num3);//5
}
}
4.包机制
包的本质是文件夹
- 包机制用于区分类名的命名区间,格式:package com.xx.xx;标识当前代码在那个文件夹下
- 导入包: import java.util.*; 导入java.util包下所有的类;
5.流程控制
1.循环语句:while,for
- 打印99乘法表
public class demo3 {
public static void main(String[] args) {
//打印99乘法表
for (int i=1;i<10;i++){
for (int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+i*j+" ");
}
System.out.println();
}
}
}
- 打印三角形:一行一行的去打印
public class demo5 {
public static void main(String[] args) {
//打印三角形
for(int i=1;i<=5;i++){
for(int j=5;j>=i;j--){
System.out.print(" ");
}
for(int j=1;j<=i;j++){
System.out.print("*");
}
for (int j=1;j<i;j++){
System.out.print("*");
}
System.out.println();
}
}
}
2.switch选择结构
注意点:
- switch表达式支持String类型和基本数据类型;
- 记得在每个case下添加break,防止case穿透
public class SwitchTest1 {
public static void main(String[] args) {
String name = "招财";
//jdk7新特性,表达式结果可以是字符串
//字符的本质还是数字
//反编译 java--class--反编译(idea)
//name.hashCode() 此处本质上判断的为字符的hashcode()值
switch (name){
case "招财":
System.out.println("招财");
break;
case "test":
System.out.println("test");
break;
default:{
System.out.println("输入有问题");
}
}
}
}
switch应用,类似map结构
public class SwitchUse {
public static void main(String[] args) {
String res = numToLetters('1');
System.out.println(res);
}
public static String numToLetters(char c){
String res;
switch (c){
case '1':
res = "abc";
break;
case '2':
res = "def";
break;
default:
res = "";
break;
}
return res;
}
}
3.增强for循环:
遍历数组和集合时使用
public class demo4 {
public static void main(String[] args) {
//z增强for循环
int[] nums = {1,2,3,4,5};
for(int num:nums){
System.out.print(num+" ");
}
}
}
4.continue,break,return
- continue终止某次循环过程,进入下一次循环;
- break:强制退出整个循环;
- return终止整个方法
6.方法
一个方法尽量只对应一个功能
1.方法重载规则
- 方法名必须相同
- 参数列表必须不同(参数个数不同,类型不同,参数排列顺序不同)
- 方法的返回类型可以相同也可以不同
public class demo1 {
public static void main(String[] args) {
}
//重载 方法名相同,参数列表不同(形参个数,形参类型,形参排列顺序不同)
public static int add(){
return 1;
}
public int add(int a){
return 1;
}
//形参格式
public int add(int a,int b){
return 1;
}
//形参类型,如返回值类型无关
public void add(double a,int b){
}
//形参顺序
public void add(int a,double b){
}
}
2.递归函数
递归结果题包括两部分:
- 递归头:什么时候不调用自身方法,及循环跳出的条件;
- 递归体:什么时候需要调用自身方法;
public class Factorial {
public static void main(String[] args) {
System.out.println(f(20));
}
//阶乘实现
public static long f(int n){
if(n==1){
return 1;
}else {
return n*f(n-1);
}
}
}
3.值传递、引用传递
//值传递
public class demo3 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);//1
demo3.change(1);
System.out.println(a);//1
}
//返回值为空
public static void change(int a){
a=10;
}
}
//引用传递:对象,本质还是值传递
public class demo4 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//null
change(person);
System.out.println(person.name);//zhaocai
}
public static void change(Person person){
//这个一个具体的人,可以改变属性
person.name = "zhaocai";
}
}
//定义一个Person对象,一个属性
class Person{
String name;
}
7.I/O
1.Scanner 获取键盘输入
常用方法
- sc.hasNext()判断键盘是否输入; sc.next() 接收输入,只能接收空格或enter键之前的数据; sc.nextLine() 接收输入,接收enter键之前的数据,包括空格字符
- 变形:对键入数据类型进行判断,包括hasNextInt(),hasNextDouble()等sc.haNextInt()判断键盘输入的是否为int类型数据 sc.nextInt() 接受int值
- ==sc.close(); 使用之后记得关闭流 ==
1.next()接收的数据是空格及enter键输入之前的数据
public class ScannerTest {
public static void main(String[] args) {
//创建扫描器对象,用于接受键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next()方法接收:");
if(scanner.hasNext()){
//使用next方式接收
/**
* 注意:next()不能得到带有空格的字符串
* */
String str = scanner.next();
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要注意及时关掉
scanner.close();
}
}
2.nextLine()接收的数据是enter键输入之前的数据
public class ScannerTest1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方式接收:");
if (scanner.hasNext()){
//使用nextline的方式进行接收
/**
* nextLine() 返回输入enter键之前的所有字符;
* */
String s = scanner.nextLine();
System.out.println("输出的内容为:" +s);
}
//关闭流
scanner.close();
}
}
3.hasNextInt(), hasNextFloat() 判断输入数据的具体类型
public class ScannerTest2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数据:");
//从键盘接收数据
if (scanner.hasNextInt()){
System.out.println("整数:"+scanner.nextInt());
}
if (scanner.hasNextFloat()){
System.out.println("小数:"+scanner.nextFloat());
}
scanner.close();
}
}
4.hastNextDouble() 判断每次输入是否是数字,直到输入的数据是非数字才会退出while循环
*输入多个数字,求总和与平均数,每输入一个数字用回车确认,
*通过输入非数字来结束输入并输出执行结果
* */
public class ScannerTest3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字:");
double sum = 0;
int times = 0;
while (scanner.hasNextDouble()){
double v = scanner.nextDouble();
times++;
sum+=v;
System.out.println("加上第"+times+"个数据后,输出和为"+sum);
}
System.out.println("和:"+sum);
System.out.println("平均数:"+(sum/times));
scanner.close();
}
}
2.scanner应用:
1.实例1
* 输入描述:
输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。
输出描述:
输出a+b的结果
输入例子1:
1 5
10 20
输出例子1:
6
30
* */
public class Example01 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int left = sc.nextInt();
int right = sc.nextInt();
System.out.println(left+right);
}
}
}
2.实例2
/*
* 输入描述:
输入第一行包括一个数据组数t(1 <= t <= 100)
接下来每行包括两个正整数a,b(1 <= a, b <= 1000)
输出描述:
输出a+b的结果
输入例子1:
2
1 5
10 20
输出例子1:
6
30
* */
public class Example02 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
if(sc.hasNext()){
int n = sc.nextInt();
for(int i=0;i<n;i++){
int left = sc.nextInt();
int right = sc.nextInt();
System.out.println(left+right);
}
}
}
}
3.实例3
/*
* 数据范围:数据组数满足 , 数据大小满足
输入描述:
输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入
输出描述:
输出a+b的结果
输入例子1:
1 5
10 20
0 0
输出例子1:
6
30
* */
public class Example03 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int left = sc.nextInt();
int right = sc.nextInt();
if(left==0&&right==0){
break;
}
System.out.println(left+right);
}
}
}
4.实例4
/*
输入描述:
输入数据包括多组。
每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。
接下来n个正整数,即需要求和的每个正整数。
输出描述:
每组数据输出求和的结果
输入例子1:
4 1 2 3 4
5 1 2 3 4 5
0
输出例子1:
10
15
* */
public class Example04 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while (sc.hasNextInt()){
int n = sc.nextInt();
if(n==0){
break;
}
int temp = 0;
for(int i=0;i<n;i++){
temp += sc.nextInt();
}
System.out.println(temp);
}
}
}
5.实例5
/**
* 输入描述:
* 输入的第一行包括一个正整数t(1 <= t <= 100), 表示数据组数。
* 接下来t行, 每行一组数据。
* 每行的第一个整数为整数的个数n(1 <= n <= 100)。
* 接下来n个正整数, 即需要求和的每个正整数。
*
* 输出描述:
* 每组数据输出求和的结果
*输入例子1:
* 2
* 4 1 2 3 4
* 5 1 2 3 4 5
*
* 输出例子1:
* 10
* 15
*
* */
public class Example05 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
if(sc.hasNextInt()){
int n = sc.nextInt();
for(int i=0;i<n;i++){
int len = sc.nextInt();
int temp = 0;
for(int j=0;j<len;j++){
temp+=sc.nextInt();
}
System.out.println(temp);
}
}
}
}
6.实例6
/*
1.计算n个数的和,然后退出 2.每n次求和,然后继续等待输入改成(while(sc.hasNext))
*/
public class Example06 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
if (sc.hasNext()){
int n = sc.nextInt();
int temp = 0;
for(int i=0;i<n;i++){
temp+=sc.nextInt();
}
System.out.println(temp);
}
}
}
7.实例7
/*
* 输入描述:
输入数据有多组, 每行表示一组输入数据。
每行不定有n个整数,空格隔开。(1 <= n <= 100)。
输出描述:
每组数据输出求和的结果
输入例子1:
1 2 3
4 5
0 0 0 0 0
输出例子1:
6
9
0
* */
public class Example07 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String str = sc.nextLine();
if(str.length() > 0){
String[] s = str.split(" ");
int sum = 0;
for(int i=0;i<s.length;i++){
sum+=Integer.valueOf(s[i]);
}
System.out.println(sum);
}
}
}
}
8.实例8
/*
* 输入描述:
输入有两行,第一行n
第二行是n个字符串,字符串之间用空格隔开
输出描述:
输出一行排序后的字符串,空格隔开,无结尾空格
输入例子1:
5
c d a bb e
输出例子1:
a bb c d e
* */
public class Example08 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
if(sc.hasNextInt()){
int n=sc.nextInt();
String[] strs = new String[n];
for(int i=0;i<n;i++){
strs[i] = sc.next();
}
Arrays.sort(strs);
for(String s:strs){
System.out.print(s+" ");
}
}
}
}
9.实例9
/*
* 输入描述:
多个测试用例,每个测试用例一行。
每行通过空格隔开,有n个字符,n<100
输出描述:
对于每组测试用例,输出一行排序过的字符串,每个字符串通过空格隔开
输入例子1:
a c bb
f dddd
nowcoder
输出例子1:
a bb c
dddd f
nowcoder
* */
public class Example09 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String tem = sc.nextLine();
String[] strs = tem.split(" ");
Arrays.sort(strs);
for (int i=0;i<strs.length;i++){
System.out.print(strs[i]+" ");
}
System.out.println();
}
}
}
10.实例10
/*
* 输入描述:
多个测试用例,每个测试用例一行。
每行通过,隔开,有n个字符,n<100
输出描述:
对于每组用例输出一行排序后的字符串,用','隔开,无结尾空格
输入例子1:
a,c,bb
f,dddd
nowcoder
输出例子1:
a,bb,c
dddd,f
nowcoder
* */
public class Example10 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String temp = sc.nextLine();
String[] strs = temp.split(",");
Arrays.sort(strs);
for(int i=0;i<strs.length;i++){
System.out.print(strs[i]);
if(i!=strs.length-1){
System.out.print(",");
}
}
System.out.println();
}
}
}
11.实例11
/* 数据范围:
输入描述:
输入有多组测试用例,每组空格隔开两个整数
输出描述:
对于每组数据输出一行两个整数的和
输入例子1:
1 1
输出例子1:
2
* */
public class Example11 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String str = sc.nextLine();
String[] s = str.split(" ");
long sum = 0;
long max = (long) (2 * Math.pow(10,10));
for (int i = 0; i < s.length; i++) {
long cur = Long.parseLong(s[i]);
if(cur <= max)
sum += cur;
}
System.out.println(sum);
}
}
}
- 数组
- 面向对象
- 异常
- 常用类
- 集合框架
- IO流
- 多线程
- 网络编程
- gui
- 注解和反射