java基础

java

java简介

语言背景

java语言是Sun公司(Stanford University Network) 在1995年推出的计算机语言

java之父:詹姆斯·高斯林(James Gosling)

2009年,Sun公司被甲骨文公司收购,所以我们现在访问oracle官 即可:https://www.oracle.com

版本

JavaSE(Java Platform Standard Edition):开发普通桌面和商务应用程序,是另外两类的基础 JavaEE(Java Platform Enterprise Edition):是为开发企业环境下的应用程序提供的一套解决方案,包含Servlet、Jsp等,主要针对Web应用程序开发 JavaME(Java Platform Micro Edition):是为开发电子消费产品和嵌入式设备提供的解决方案

特性

特性(百度搜索)

  1. 简单性 Java看起来设计得很像C++,但是为了使语言小和容易熟悉,设计者们把C++语言中许多可用的特征去掉了,这些特征是一般程序员很少使用的。例如,Java不支持go to语句,代之以提供break和continue语句以及异常处理。Java还剔除了C++的操作符过载(overload)和多继承特征,并且不使用主文件,免去了预处理程序。因为Java没有结构,数组和串都是对象,所以不需要指针。Java能够自动处理对象的引用和间接引用,实现自动的无用单元收集,使用户不必为存储管理问题烦恼,能更多的时间和精力花在研发上。 2.面向对象 Java是一个面向对象的语言。对程序员来说,这意味着要注意应中的数据和操纵数据的方法(method),而不是严格地用过程来思考。在一个面向对象的系统中,类(class)是数据和操作数据的方法的集合。数据和方法一起描述对象(object)的状态和行为。每一对象是其状态和行为的封装。类是按一定体系和层次安排的,使得子类可以从超类继承行为。在这个类层次体系中有一个根类,它是具有一般行为的类。Java程序是用类来组织的。 Java还包括一个类的扩展集合,分别组成各种程序包(Package),用户可以在自己的程序中使用。例如,Java提供产生图形用户接口部件的类(java.awt包),这里awt是抽象窗口工具集(abstract windowing toolkit)的缩写,处理输入输出的类(java.io包)和支持 络功能的类(java.net包)。 3.分布性 Java设计成支持在 络上应用,它是分布式语言。Java既支持各种层次的 络连接,又以Socket类支持可靠的流(stream) 络连接,所以用户可以产生分布式的客户机和服务器。 络变成软件应用的分布运载工具。Java程序只要编写一次,就可到处运行。 4.编译和解释性 Java编译程序生成字节码(byte-code),而不是通常的机器码。Java字节码提供对体系结构中性的目标文件格式,代码设计成可有效地传送程序到多个平台。Java程序可以在任何实现了Java解释程序和运行系统(run-time system)的系统上运行。 在一个解释性的环境中,程序开发的标准“链接”阶段大大消失了。如果说Java还有一个链接阶段,它只是把新类装进环境的过程,它是增量式的、轻量级的过程。因此,Java支持快速原型和容易试验,它将导致快速程序开发。这是一个与传统的、耗时的“编译、链接和测试”形成鲜明对比的精巧的开发过程。 5.稳健性 ? Java原来是用作编写消费类家用电子产品软件的语言,所以它是被设计成写高可靠和稳健软件的。Java消除了某些编程错误,使得用它写可靠软件相当容易。 Java是一个强类型语言,它允许扩展编译时检查潜在类型不匹配问题的功能。Java要求显式的方法声明,它不支持C风格的隐式声明。这些严格的要求保证编译程序能捕捉调用错误,这就导致更可靠的程序。 可靠性方面最重要的增强之一是Java的存储模型。Java不支持指针,它消除重写存储和讹误数据的可能性。类似地,Java自动的“无用单元收集”预防存储漏泄和其它有关动态存储分配和解除分配的有害错误。Java解释程序也执行许多运行时的检查,诸如验证所有数组和串访问是否在界限之内。 异常处理是Java中使得程序更稳健的另一个特征。异常是某种类似于错误的异常条件出现的信 。使用try/catch/finally语句,程序员可以找到出错的处理代码,这就简化了出错处理和恢复的任务。 6.安全性 Java的存储分配模型是它防御恶意代码的主要方法之一。Java没有指针,所以程序员不能得到隐蔽起来的内幕和伪造指针去指向存储器。更重要的是,Java编译程序不处理存储安排决策,所以程序员不能通过查看声明去猜测类的实际存储安排。编译的Java代码中的存储引用在运行时由Java解释程序决定实际存储地址。 Java运行系统使用字节码验证过程来保证装载到 络上的代码不违背任何Java语言限制。这个安全机制部分包括类如何从 上装载。例如,装载的类是放在分开的名字空间而不是局部类,预防恶意的小应用程序用它自己的版本来代替标准Java类。 7.可移植性 Java使得语言声明不依赖于实现的方面。例如,Java显式说明每个基本数据类型的大小和它的运算行为(这些数据类型由Java语法描述)。 Java环境本身对新的硬件平台和操作系统是可移植的。Java编译程序也用Java编写,而Java运行系统用ANSIC语言编写。 8.高性能 Java是一种先编译后解释的语言,所以它不如全编译性语言快。但是有些情况下性能是很要紧的,为了支持这些情况,Java设计者制作了“及时”编译程序,它能在运行时把Java字节码翻译成特定CPU(中央处理器)的机器代码,也就是实现全编译了。 Java字节码格式设计时考虑到这些“及时”编译程序的需要,所以生成机器代码的过程相当简单,它能产生相当好的代码。 9.多线程性 Java是多线程语言,它提供支持多线程的执行(也称为轻便过程),能处理不同任务,使具有线索的程序设计很容易。Java的lang包提供一个Thread类,它支持开始线索、运行线索、停止线索和检查线索状态的方法。 Java的线索支持也包括一组同步原语。这些原语是基于监督程序和条件变量风范,由C.A.R.Haore开发的广泛使用的同步化方案。用关键词synchronized,程序员可以说明某些方法在一个类中不能并发地运行。这些方法在监督程序控制之下,确保变量维持在一个一致的状态。 10.动态性 Java语言设计成适应于变化的环境,它是一个动态的语言。例如,Java中的类是根据需要载入的,甚至有些是通过 络获取的。 [24]

跨平台原理

Java程序并非是直接运行的,Java编译器将Java源程序编译成与平台无关的字节码文件(class文件),然后由Java虚拟机(JVM)对字节码文件解释执行。所以在不同的操作系统下,只需安装不同的Java虚拟机即可实现java程序的跨平台

即一次编译,到处运行 .class 它本身是二进制文件,但是不可以被系统直接执行,而是需要虚拟机解释执行。

开发运行流程

编写代码

编译代码

.java属于源文件,无法被JVM所识别执行,这一步的目的 使用jdk中的翻译工具,将其翻译成jvm可以直接识别的

运行代码

将生成的.class运行在JVM虚拟机中

JDK,JRE,JVM

  • JDK(Java Development Kit)称为Java开发工具,包含了JRE和开发工具
  • JRE(Java Runtime Environment),Java运行环境,包含了JVM和Java的核心类库(Java API)
  • JVM(Java Virtual Machine),Java虚拟机 总结:我们只需安装JDK即可,它包含了java的运行环境和虚拟机。
  • 语言基础

    注释

    单行注释

    // 这是单行注释文字

    多行注释

    /* 注释 */

    文档注释

    /** 注释 */

    关键字

    概念

    关键字是指被java语言赋予了特殊含义的单词。

    特点

    关键字的字母全部小写。

    数据类型

    5.1 计算机存储单元 我们知道计算机是可以用来存储数据的,但是无论是内存还是硬盘,计算机存储设备的最小信息单元叫“位(bit)”,我们又称之为“比特位”,通常用小写的字母”b”表示。而计算机中最基本的存储单元叫“字节(byte)”, 通常用大写字母”B”表示,字节是由连续的8个位组成。 除了字节外还有一些常用的存储单位,其换算单位如下: 1B(字节) = 8bit 1KB = 1024B 1MB = 1024KB 1GB = 1024MB 1TB = 1024GB 5.2 Java中的数据类型 Java是一个强类型语言,Java中的数据必须明确数据类型。在Java中的数据类型包括基本数据类型和引用数据类型两种。 Java中的基本数据类型: 数据类型 关键字 内存占用 取值范围 包装类 整数类型 byte 1 -128~127 Byte

    short 2 -32768~32767 Short

    int(默认) 4 -2的31次方到2的31次方-1 Integer

    long 8 -2的63次方到2的63次方-1 Long 浮点类型 float 4 负数:-3.402823E+38到-1.401298E-45 正数: 1.401298E-45到3.402823E+38 Float

    double(默认) 8 负数:-1.797693E+308到-4.9000000E-324 正数:4.9000000E-324 到1.797693E+308 Double 字符类型 char 2 0-65535 Character 布尔类型 boolean 1 true,false Boolean

    说明: e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方。 在java中整数默认是int类型,浮点数默认是double类型。

    常量

    概念

    在程序运行过程中,其值不可以发生改变的量。

    分类

    除空常量外,其他常量均可使用输出语句直接输出。 public class Demo { public static void main(String[] args) { System.out.println(10); // 输出一个整数 System.out.println(5.5); // 输出一个小数 System.out.println(‘a’); // 输出一个字符 System.out.println(true); // 输出boolean值true System.out.println(“欢迎来到黑马程序员”); // 输出字符串 } }

    字符串常量 用双引 括起来的多个字符(可以包含0个、一个或多个),例如”a”、”abc”、”中国”等 整数常量 整数,例如:-10、0、88等 小数常量 小数,例如:-5.5、1.0、88.88等 字符常量 用单引 括起来的一个字符,例如:’a’、’5’、’B’、’中’等 布尔常量 布尔值,表示真假,只有两个值true和false 空常量 一个特殊的值,空值,值为null

    变量

    定义

    概念

    在程序运行过程中,其值可以发生改变的量。

    从本质上讲,变量是内存中的一小块区 域,其值可以在一定范围内变化。 数据类型 变量名 = 初始化值; // 声明变量并赋值 int age = 18; System.out.println(age);

    修改

    int a = 10; a = 30; //修改变量的值 System.out.println(a);

    注意事项

    1. 在同一对花括 中,变量名不能重复。
    2. 变量在使用之前,必须初始化(赋值)。
    3. 定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。因为整数默认是int类型,整数太大可能超出int范围。
    4. 定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。因为浮点数的默认类型是double, double的取值范围是大于float的,类型不兼容。

    标识符

    标识符是用户编程时使用的名字,用于给类、方法、变量、常量等命名。

    规则

    1. 由字母、数字、下划线“_”、美元符 “$”组成,第一个字符不能是数字。
    2. 不能使用java中的关键字作为标识符。
    3. 标识符对大小写敏感(区分大小写)。

    运算符和表达式

    概念

    运算符:对常量或者变量进行操作的符

    表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。

       不同运算符连接的表达式体现的是不同类型的表达式

    举例说明: int a = 10; int b = 20; int c = a + b; +:是运算符,并且是算术运算符。 a + b:是表达式,由于+是算术运算符,所以这个表达式叫算术表达式。

    运算符分类

    算数运算符 关系运算符 逻辑运算符 赋值运算符 自增自减运算符 三元运算符 位运算符

    类型转化

    隐式转换

    概念

    把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。这种转换方式是自动的,直接书写即可

    double num = 10; // 将int类型的10直接赋值给double类型 System.out.println(num); // 输出10.0

    数据范围从小到大图

    强制转换

    概念

    把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。

    强制类型转换格式:目标数据类型 变量名 = (目标数据类型)值或者变量;

    double num1 = 5.5; int num2 = (int) num1; // 将double类型的num1强制转换为int类型 System.out.println(num2); // 输出5(小数位直接舍弃)

    流程控制

    分类

    顺序

    顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

    条件

    if switch

    循环

    for

    for增强 while do..while

    循环控制

    break continue

    死循环

    1. for(;;){}
    2. while(true){}
    3. do {} while(true);

    进制

    实例

    代码 : public class Demo1 { /* 十进制:Java中,数值默认都是10进制,不需要加任何修饰。 二进制:数值前面以0b开头,b大小写都可以。 八进制:数值前面以0开头。 十六进制:数值前面以0x开头,x大小写都可以。

       注意: 书写的时候, 虽然加入了进制的标识, 但打印在控制台展示的都是十进制数据.*/

    public static void main(String[] args) { System.out.println(10); System.out.println(“二进制数据0b10的十进制表示为:” + 0b10); System.out.println(“八进制数据010的十进制表示为:” + 010); System.out.println(“十六进制数据0x10的十进制表示为:” + 0x10); } }

    任意进制到十进制的转换

    二进制到十进制

    十六进制到十进制

    十进制到任意进制转换

    十进制到二进制的转换

    十进制到十六进制的转换

    快速进制转换法

    8421码又称为BCD码,是十进制代码中最常用的一种。在这种编码方式中,每一位二值代码的“1”都代表一个固定数值。将每位“1”所代表的二进制数加起来就可以得到它所代表的十进制数字。因为代码中从左至右看每一位“1”分别代表数字“8”“4”“2”“1”,故得名8421码。其中每一位“1”代表的十进制数称为这一位的权。因为每位的权都是固定不变的,所以8421码是恒权码。

    计算器结果

    原码反码补码

    原码反码补码

    win10上的程序员计算器

    cmd命令calc

    数组

    概念

    数组就是存储数据长度固定的容器,存储多个数据的数据类型要一致。 

    定义格式

    1. 数据类型[] 数组名

    int[] arr;

    2. 数据类型 数组名[]

    int arr[];

    初始化

    静态初始化

    完整格式

    数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};

    简化格式

    数据类型[] 数组名 = {元素1,元素2,…};

    动态初始化

    数据类型[] 数组名 = new 数据类型[数组长度];

    int[] arr = new int[3];

    实例(打印)

    代码 : package com.itheima.array;

    public class Demo2Array { /* 数组的动态初始化: 在初始化的时候, 需要手动指定数组的长度, 系统会为数组容器分配初始值.

       动态初始化格式:                   数据类型[] 数组名 = new 数据类型[数组的长度];   注意:                   打印数组变量的时候, 会打印出数组的内存地址   [I@10f87f48 :                   @ : 分隔符                   [ : 当前的空间是一个数组类型                   I : 当前数组容器中所存储的数据类型                   10f87f48 : 十六进制内存地址                           0 1 2 3 4 5 6 7 8 9 a b c d e f*/

    public static void main(String[] args) { // 数据类型[] 数组名 = new 数据类型[数组的长度]; // 通过new关键字创建了一个int类型的数组容器, 该容器可以存储5个int类型的整数, 该容器被arr数组变量所记录 int[] arr = new int[5]; // [I@10f87f48 System.out.println(arr);

       byte[] bArr = new byte[3];   // [B@b4c966a   System.out.println(bArr);

    } }

    遍历

    public class ArrayTest01 { public static void main(String[] args) { //定义数组 int[] arr = {11, 22, 33, 44, 55};

        //使用通用的遍历格式    for(int x=0; x<arr.length; x++) {        System.out.println(arr[x]);    }}

    }

    常见问题

    索引越界异常

    ArrayIndexOutOfBoundsException

    空指针异常

    NullPointerException

    经典操作

    获取最大值

    public class Test2Array { /* 需求: 从数组中查找最大值

                int[] arr = {12,45,98,73,60};    实现步骤:            1. 假设数组中的第一个元素为最大值            2. 遍历数组, 获取每一个元素, 准备进行比较            3. 如果比较的过程中, 出现了比max更大的, 让max记录更大的值            4. 循环结束后, 打印最大值. */public static void main(String[] args) {    int[] arr = {12,45,98,73,60};    // 1. 假设数组中的第一个元素为最大值    int max = arr[0];    // 2. 遍历数组, 获取每一个元素, 准备进行比较    for(int i = 1; i < arr.length; i++){        // 3. 如果比较的过程中, 出现了比max更大的, 让max记录更大的值        if(arr[i] > max){            max = arr[i];        }    }    //  4. 循环结束后, 打印最大值.    System.out.println("max:" + max);}

    }

    查找

    需求: 已知一个数组 arr = {19, 28, 37, 46, 50}; 键盘录入一个数据,查找该数据在数组中的索引,并在控制台输出找到的索引值。

    代码实现:

    public static void main(String[] args) { // 1.定义一个数组,用静态初始化完成数组元素的初始化 int[] arr = {19, 28, 37, 46, 50}; // 2.键盘录入要查找的数据,用一个变量接收 Scanner sc = new Scanner(System.in); System.out.println(“请输入您要查找的元素:”); int num = sc.nextInt(); // 3.定义一个索引变量,初始值为-1 // 假设要查找的数据, 在数组中就是不存在的 int index = -1; // 4.遍历数组,获取到数组中的每一个元素 for (int i = 0; i < arr.length; i++) { // 5.拿键盘录入的数据和数组中的每一个元素进行比较,如果值相同,就把该值对应的索引赋值给索引变量,并结束循环 if(num == arr[i]){ // 如果值相同,就把该值对应的索引赋值给索引变量,并结束循环 index = i; break; } } // 6.输出索引变量 System.out.println(index); } }

    数组求和

    public class Test3Array { /* 需求:键盘录入5个整数,存储到数组中,并对数组求和

        思路:        1.创建键盘录入对象,准备键盘录入        2.定义一个求和变量,准备记录累加后的结果        3.动态初始化一个长度为5int数组,准备存储键盘录入的数值        4.将键盘录入的数值存储到数组中        5.遍历数组,取出每一个元素,并求和        6.输出总和 */public static void main(String[] args) {    // 1.创建键盘录入对象,准备键盘录入    Scanner sc = new Scanner(System.in);    // 2.定义一个求和变量,准备记录累加后的结果    int sum = 0;    // 3.动态初始化一个长度为5的int数组,准备存储键盘录入的数值    int[] arr = new int[5];    // 4.将键盘录入的数值存储到数组中    for(int i = 0; i < arr.length; i++){        System.out.println("请输入第" + (i+1) + "个整数:");        //arr[i] = 10;        arr[i] = sc.nextInt();    }    // 5.遍历数组,取出每一个元素,并求和    for (int i = 0; i < arr.length; i++) {        sum += arr[i];    }    // 6.输出总和    System.out.println("sum:" + sum);}

    }

    高级操作

    二分查找

    10.1 二分查找 (理解)

    二分查找概述

    查找指定元素在数组中的位置时,以前的方式是通过遍历,逐个获取每个元素,看是否是要查找的元素,这种方式当数组元素较多时,查找的效率很低

    二分查找也叫折半查找,每次可以去掉一半的查找范围,从而提高查找的效率 需求 在数组{1,2,3,4,5,6,7,8,9,10}中,查找某个元素的位置 实现步骤 定义两个变量,表示要查找的范围。默认min = 0 ,max = 最大索引 循环查找,但是min <= max 计算出mid的值 判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引 如果要查找的值在mid的左半边,那么min值不变,max = mid -1.继续下次循环查找 如果要查找的值在mid的右半边,那么max值不变,min = mid + 1.继续下次循环查找 当min > max 时,表示要查找的元素在数组中不存在,返回-1. 代码实现 public class MyBinarySearchDemo { public static void main(String[] args) { int [] arr = {1,2,3,4,5,6,7,8,9,10}; int number = 11;

       //1,我现在要干嘛? --- 二分查找   //2.我干这件事情需要什么? --- 数组 元素   //3,我干完了,要不要把结果返回调用者 --- 把索引返回给调用者   int index = binarySearchForIndex(arr,number);   System.out.println(index);

    }

    private static int binarySearchForIndex(int[] arr, int number) { //1,定义查找的范围 int min = 0; int max = arr.length – 1; //2.循环查找 min <= max while(min <= max){ //3.计算出中间位置 mid int mid = (min + max) >> 1; //mid指向的元素 > number if(arr[mid] > number){ //表示要查找的元素在左边. max = mid -1; }else if(arr[mid] < number){ //mid指向的元素 < number //表示要查找的元素在右边. min = mid + 1; }else{ //mid指向的元素 == number return mid; } } //如果min大于了max就表示元素不存在,返回-1. return -1; }

    }

    注意事项 有一个前提条件,数组内的元素一定要按照大小顺序排列,如果没有大小顺序,是不能使用二分查找法的

    冒泡排序

    冒泡排序概述 一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序 如果有n个数据进行排序,总共需要比较n-1次 每一次比较完毕,下一次的比较就会少一个数据参与 代码实现 public class MyBubbleSortDemo2 { public static void main(String[] args) { int[] arr = {3, 5, 2, 1, 4}; //1 2 3 4 5 bubbleSort(arr); }

    private static void bubbleSort(int[] arr) { //外层循环控制的是次数 比数组的长度少一次. for (int i = 0; i < arr.length -1; i++) { //内存循环就是实际循环比较的 //-1 是为了让数组不要越界 //-i 每一轮结束之后,我们就会少比一个数字. for (int j = 0; j < arr.length – 1 – i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } }

       printArr(arr);

    }

    private static void printArr(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + ” “); } System.out.println(); }

    }

    快速排序

    10.3 快速排序 (理解) 快速排序概述 冒泡排序算法中,一次循环结束,就相当于确定了当前的最大值,也能确定最大值在数组中应存入的位置 快速排序算法中,每一次递归时以第一个数为基准数,找到数组中所有比基准数小的.再找到所有比基准数大的.小的全部放左边,大的全部放右边,确定基准数的正确位置 核心步骤 从右开始找比基准数小的 从左开始找比基准数大的 交换两个值的位置 红色继续往左找,蓝色继续往右找,直到两个箭头指向同一个索引为止 基准数归位 代码实现 public class MyQuiteSortDemo2 { public static void main(String[] args) { // 1,从右开始找比基准数小的 // 2,从左开始找比基准数大的 // 3,交换两个值的位置 // 4,红色继续往左找,蓝色继续往右找,直到两个箭头指向同一个索引为止 // 5,基准数归位 int[] arr = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};

       quiteSort(arr,0,arr.length-1);   for (int i = 0; i < arr.length; i++) {       System.out.print(arr[i] + " ");  }

    }

    private static void quiteSort(int[] arr, int left, int right) { // 递归结束的条件 if(right < left){ return; }

       int left0 = left;   int right0 = right;   //计算出基准数   int baseNumber = arr[left0];   while(left != right){

    // 1,从右开始找比基准数小的 while(arr[right] >= baseNumber && right > left){ right–; }

    // 2,从左开始找比基准数大的 while(arr[left] <= baseNumber && right > left){ left++; } // 3,交换两个值的位置 int temp = arr[left]; arr[left] = arr[

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2022年8月26日
    下一篇 2022年8月26日

    相关推荐