java se 快速入门
文章目录
- java se 快速入门
- Java 简介
- Java的优点
- jdk 和 jre
- 安装jdk配置环境变量
- Java 语法快速入门
- 程序入口
- 文件名
- 类规范
- 基本语法
- 注释
- 变量和常量
- 输入输出
- 条件语句
- 循环语句
- 基本数据类型
- Java字符串常用方法
- 字符串拼接
- java字节数组和字符串相互转化
- java字符数组和字符串相互转换
- java字节数组转python字符串
- Java的Object类
- object 类的方法
- 获取Object类型变量的具体类型
- 容器类型之List
- 基本使用
- 常用方法
- 容器类型之Set
- 基本使用
- 交叉并集
- 容器类型之Map
- 基本使用
- 常用操作
- 面向对象
- 类的定义规范
- 类属性
- 成员方法
- 构造方法
- this关键字
- 访问控制修饰符
- 静态变量和静态方法
- 面向对象之继承
- 构造方法
- super与this关键字
- 重写与重载
- 面向对象之接口
- 接口的定义
- 接口继承
- 接口实现
- 面向对象之抽象类
- 面向对象之封装
- 面向对象之多态
- 通过类继承实现多态
- 通过接口实现多态
- Java 中包
- 包的作用
- 引入包使用
java se 快速入门
Java 简介
Java是一种高级编程语言,由Sun Microsystems公司于1995年推出。Java具有跨平台性、面向对象、健壮性、安全性、可移植性等特点,被广泛应用于企业级应用开发、移动应用开发、大数据处理、云计算等领域。Java程序可以在不同的操作系统上运行,只需编译一次,就可以在任何支持Java虚拟机(JVM)的平台上运行。Java还提供了丰富的库和框架,可以加快开发过程,提高开发效率。
java 体系
- java se:java基础-- 如果做java web方向开发和 安卓开发,这个必学
- java ee:java web方向–只有做web方向开发,才需要学,主要是 SpringBoot,springCloud ,java web后端工程师又被称为 spring 工程师
- java me:过时了,java手机方向开发
Java的优点
- 面向对象:Java是一种面向对象的编程语言,支持封装、继承和多态等面向对象的特性,使得代码更易于理解、维护和重用。
- 跨平台性:Java应用程序可以在不同的操作系统上运行,只需编译一次,就可以在任何支持Java虚拟机(JVM)的平台上运行。
- 强大的生态系统:Java拥有庞大而活跃的开源社区,提供了丰富的库和框架,可以加快开发过程,提高开发效率。
- 内存管理:Java提供了自动的垃圾回收机制,开发者不需要手动管理内存,减少了内存泄漏和野指针等问题。
- 安全性:Java具有强大的安全性特性,包括沙箱安全模型、字节码验证和安全类加载等机制,可以防止恶意代码的执行。
- 多线程支持:Java内置了对多线程的支持,可以方便地创建和管理多线程应用程序,提高程序的并发性能。
- 广泛应用:Java广泛应用于企业级应用开发、移动应用开发、大数据处理、云计算等领域,具有良好的可扩展性和稳定性。
jdk 和 jre
jdk包含jre,jre包含jvm
jdk:Java Development Kit ,java集成开发工具包,java开发者必须装这个,才能做java开发
jre:Java Runtime Environment 即Java运行环境 , 如果只想运行java应用,只需要装它即可
但是,好多人运行java应用,也装jdk
jvm:java虚拟机,java的字节码文件,必须运行在jvm上, 正因为jvm的存在,java代码才夸平台,一处编码处处运行, 可以在不同平台(win,mac,linux)安装不同平台的jvm,java字节码文件就可以运行在不同平台
安装jdk配置环境变量
jdk 安装教程
### 配置环境变量
# 1 新建 JAVA_HOME
JAVA_HOME D:\Program Files\Java\jdk-1.8
# 2 新建 CLASSPATH【第一个是. 表示当前路径】
CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
# 3 path 加入两个环境变量
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
Java 语法快速入门
程序入口
java 程序是有入口的,从入口处开始执行
java程序入口为类中的static的viod的main函数,参数固定为字符串数组
public static void main(String[] args) {
# 入口
}
文件名
- 一个java文件中,最多只能有一个public的类,并且文件名必须跟public类同名
- 一个java文件中,可以有多个类,但是文件名跟public的类名一致,其他类不能使用public修饰
- 一个java文件中,有多个类,没有public修饰的类,文件名可以随意
// Main.java
public class Main {
public static void main(String[] args) {
// Press Opt+Enter with your caret at the highlighted text to see how
// IntelliJ IDEA suggests fixing it.
System.out.printf("Hello and welcome!");
// Press Ctrl+R or click the green arrow button in the gutter to run the code.
for (int i = 1; i <= 5; i++) {
// Press Ctrl+D to start debugging your code. We have set one breakpoint
// for you, but you can always add more by pressing Cmd+F8.
System.out.println("i = " + i);
}
}
}
类规范
-
类名规范: 类名首字母大写且驼峰式命名, 例如 UserInfo、PersonApplication
-
类有修饰符, 需要写在类前面的 public , default(不写)
-
类中有成员(变量,方法),在类中,有四个关键字修饰成员public ,private,protected,default(不写)
- public:公有的,所有其他类中都可以使用
- private:私有的,只有在当前类中可以使用
- protected:受保护的,只有在当前包下的类中可以使用
- default(不写):默认
class Person{ String name; // 成员变量 int add(int a,int b){ // 成员方法 return a+b; } }
-
静态成员方法(使用static): 给类来的调用的,不需要 实例化得到对象,类直接来用 等同于python中,使用classmethod修饰的方法
```java
class Person{
static String name = “person1”;
static int add(int a, int b){
return a + b;
};
} -
返回值: void 表示函数没有返回值, 有返回值的函数,就需要写返回值类型
基本语法
注释
// 1 单行注释
以双斜杠“//”标识,只能注释一行内容,用在注释信息内容少的地方
快捷键:【注释 ctrl+/ 】 【 取消注释 ctrl+/ 】
// 2 多行注释
包含在“/*”和“*/”之间,能注释很多行的内容,可以换行
快捷键:【注释 ctrl+shift+/ 】 【取消注释 ctrl+shift+\ 】
// 3 文档注释
包含在“/**”和“*/”之间,也能注释多行内容,一般用在类、方法和变量上面,用来描述其作用。注释后,鼠标放在类和变量上面会自动显示出我们注释的内容
/**
*
* @param a
* @param b
*/
public static void add(int a, int b) {
System.out.println(a + b);
System.out.println(name);
}
变量和常量
public class Demo02 {
// 变量和常量
// 变量: 先写类型,再写变量名,有修饰符
public String name;
public int age;
public static void main(String[] args) {
// 定义在方法中的变量,不能再用 修饰符修饰了
String hobby="抽烟";
hobby="烫头";
System.out.println(hobby);
// 常量 使用 final 修饰,恒定不变的量,以后不会变
final String school="清华大学";
school="北京大学"; //报错
}
}
//python中没有常量,于是才约定俗成全大写表示常量
输入输出
// 输入:从控制台输入用的不多
// 输出:打印得到控制台,用的比较多
import java.util.Scanner;
public class Demo03 {
// 输入和输出
public static void main(String[] args) {
// 输出1:输出换行
System.out.println("表示输出并换行");
// 输出2:输出不换行
System.out.print("你");
System.out.print("好");
System.out.print("\n");
// 输出3,格式化输出
String name="justin";
System.out.printf("我的名字是:%s\n",name);
// 输入:控制台输入用户名,打印出来-->看看了解即可
System.out.println("请输入您的名字:");
Scanner input=new Scanner(System.in);
String inputName=input.nextLine(); // 接收控制台输入数据
System.out.printf("您输入的名字是:%s",inputName);
}
}
java 中转换符如下
条件语句
// 控制台输入一个数字--》打印它的成绩:优秀,良好,及格,不及格
import java.util.Scanner;
public class Demo04 {
// 条件语句
public static void main(String[] args) {
// 1 接受用户输入
System.out.println("请输入您的分数:");
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
if (score >= 90 && score <= 100) {
System.out.println("优秀");
} else if (score >= 80 && score < 90) {
System.out.println("良好");
} else if (score >= 60 && score < 80) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
}
}
switch
import java.util.Scanner;
public class Demo05 {
// switch 语句
public static void main(String[] args) {
System.out.println("请输入您的分数:");
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
switch (score) {
case 99:
System.out.println("恭喜您99分");
break;
case 88:
System.out.println("恭喜您88分");
break;
default:
System.out.println("不知道多少分");
}
}
}
循环语句
while
do while
for
break和continue 任何语言都一样
public class Demo06 {
public static void main(String[] args) {
//1 while 循环,循环打印0--9
int count =0;
while (count<10){
System.out.println(count);
count++;
}
// 2 do while 循环,循环打印0--9 ,do 内的至少会执行一次
int count2 =0;
do{
System.out.println(count2);
count2++;
}while (count<10);
// 3 for 循环
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}
基本数据类型
byte 带符号的整形 8个比特位--1个bytes 表示数字范围: -128---127之间
short 带符号的整形 16个比特位--2个bytes 表示数字范围: -2的15次方---+2的15次方-1 32768 ~ 32767
int 带符号的整形 32个比特位--4个bytes 表示数字范围: -2的31次方---+2的31次方-1
long 带符号字节型 64个比特位--8个bytes 表示数字范围:-9223372036854775808 ~ 9223372036854775807
float 表示小数点后位数不一样 大约小数点后7位左右
doube 表示小数点后位数不一样 大约小数点后15位左右
char 字符类型
String 字符串类型,准确点说是String 对象
数组类型
int[] String[] char[] short[]
boolean 布尔类型
demo
// 字节类型 ascii
byte b = 'A';
byte b2 = 65;
System.out.println(b); // 65 默认输出10进制
// 打印字符方案一
byte[] byteArray = new byte[]{b};
String str = new String(byteArray);
System.out.println(str); // A
// 方案二
System.out.printf("b的值是: %c" , b); // A
// 布尔类型
boolean show =true;
show=false;
System.out.println(show); // false
show=0<1;
System.out.println(show); // true
// 字符类型
char c='中'; // char 类型只能用打印号
char c1='x';
System.out.printf("%c",c);
// 字符串类型
String s1="jason"; // 字符串只能用双引号
System.out.println(s1);
String s2=new String("彭于晏");
String s3 = new String(new byte[]{-27, -67, -83, -28, -70, -114, -26, -103, -113});
String s4 = new String(new char[]{'彭','于','盐'});
System.out.println(s4);
// 数组类型
int[] i3=new int[]{2,3,4};
System.out.println(i3); // [I@4b67cf4d
System.out.println(Arrays.toString(i3)); // [2, 3, 4]
String[] ss1=new String[]{"小红","小绿"};
System.out.println(ss1); // [Ljava.lang.String;@7ea987ac
System.out.println(Arrays.toString(ss1)); // [小红, 小绿]
// 按位置取值赋值
ss1[0]="xxx";
System.out.println(Arrays.toString(ss1));
System.out.println(ss1[1]);
Java字符串常用方法
import java.util.Arrays;
import java.util.Locale;
public class Demo01 {
public static void main(String[] args) {
// java字符串常用方法
String origin = "hello world 中国";
// 1 取指定位置字符
char v1=origin.charAt(13);
System.out.println(v1);
// 2 循环每个字符 origin.length() 字符长度
for (int i = 0; i < origin.length(); i++) {
char item = origin.charAt(i);
System.out.println(item);
}
// 3 去除前后空白
String v2=origin.trim();
System.out.println(v2);
//4 转大写,小写
String v3=origin.toUpperCase();
String v4=origin.toLowerCase();
System.out.println(v3);
System.out.println(v4);
// 5 按 某个字符分割
String[] v5=origin.split(" ");
System.out.println(v5);
System.out.println(Arrays.toString(v5));
// 6 字符串替换
String v6= origin.replace("he","l");
System.out.println(v6);
// 7 字符串切片
String v7=origin.substring(2,7);
System.out.println(v7);
// 8 比较字符串是否相等
boolean b=origin.equals("hello world 中国");
System.out.println(b);
// 9 字符串包含
System.out.println(origin.contains("中国"));
// 10 是否以 xx 开头
System.out.println(origin.startsWith("he"));
// 11 字符末尾追加
String v8=origin.concat("hello");
System.out.println(v8);
}
}
字符串拼接
public class Demo02 {
public static void main(String[] args) {
// 字符串拼接
// 1 使用 + 很少用,效率很低
String s ="hello" +"中国";
System.out.println(s);
// 2 经常见到,高效方式 StringBuffer StringBuilder(多)
StringBuilder sb=new StringBuilder();
// StringBuffer sb=new StringBuffer(); // 线程安全--》多线程情况下,使用它,比较少
sb.append("hello");
sb.append("world");
sb.append(" ");
sb.append("@");
sb.append("中国");
System.out.println(sb.toString());
}
}
java字节数组和字符串相互转化
import java.util.Arrays;
public class Demo03 {
public static void main(String[] args) throws Exception {
// java字节数组和字符串相互转化--->涉及到编码格式
// 1 字符串转字节数组
String v4 = "hello中"; // utf编码,3个字节表示一个字符 -28, -72, -83 是 中 字
// byte[] b =v4.getBytes(); // 默认是utf-8,可以传参数指定编码格式 python 的encode --》后面会经常见--》字符串转成字节数组
try {
byte[] b = v4.getBytes("GBK"); // 会报错,可能转不了--》异常捕获
System.out.println(Arrays.toString(b)); // -42, -48 gbk编码,两个字节表示一个字符
} catch (Exception e) {
System.out.println(e);
}
// 2 字节数组转字符串
byte[] b1 = new byte[]{104, 101, 108, 108, 111, -42, -48};
// String vv8=new String(b1); // 默认使用utf-8
String vv8 = new String(b1, "GBK"); // 默认使用utf-8
System.out.println(vv8);
}
}
java字符数组和字符串相互转换
import java.util.Arrays;
public class Demo04 {
public static void main(String[] args) {
// java字符数组和字符串相互转换---》反编译的代码中少见
// 1 字符数组转字符串
char[] c=new char[]{'彭','于','盐'};
String v1=new String(c);
System.out.println(v1); // 彭于盐
// 2 字符串转字符数组
String v2="彭于盐";
char[] c2=v2.toCharArray();
System.out.println(c2); // 彭于盐
System.out.println(Arrays.toString(c2)); // [彭, 于, 盐]
}
}
java字节数组转python字符串
#1 java字节数组转python字符串 都用十进制表示,不一样
python: [229, 189, 173, 228, 186, 142, 230, 153, 143]
java : [-27, -67, -83, -28, -70, -114, -26, -103, -113]
#2 字节有无符号
Python字节无符号(不含负数): 0 ~ 255
0 1 2 3 4 5 ... 127 128 129 130 ... 255
Java字节是有符号(含有负数):-128 ~ 127
0 1 2 3 4 5 ...127 -128 -127 - 126 -125 .... -2 -1
# 3 写一个java的字节数组转成python字符串的代码
v1 = [-27, -67, -83, -28, -70, -114, -26, -103, -113]
# 转成字符串---》转成python的 字符 列表[bytearray]---》把字符列表转成字符串
def java_arr_to_python_str(v1):
num_list = bytearray()
for i in v1:
if i < 0:
i = i + 256
num_list.append(i)
return num_list.decode("utf-8")
if __name__ == '__main__':
print(java_arr_to_python_str(v1))
Java的Object类
Object 类是 java.lang 包下的核心类,Object 是所有类的父类,任何一个类如果没有明确表示继承一个父类,它就是Object的子类,和python 里面的 object 类一样
// 以下两个是一个意思
class Person{}
class Person extends Object{}
// python3 中一个类,如果没有显示继承某个类,就是继承了object类
class Person():
pass
class Person(object):
pass
object 类的方法
// 1. clone()
保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
// 2. getClass()
final方法,返回Class类型的对象,反射来获取对象。
//3. toString()
该方法用得比较多,一般子类都有覆盖,来获取对象的信息。
//4. finalize()
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
//5. equals()
比较对象的内容是否相等
// 6. hashCode()
该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
// 7. wait()
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
其他线程调用了该对象的notify方法。
其他线程调用了该对象的notifyAll方法。
其他线程调用了interrupt中断该线程。
时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
// 8. notify()
该方法唤醒在该对象上等待的某个线程。
//9. notifyAll()
该方法唤醒在该对象上等待的所有线程。
/* 常用的
getClass() # 获得这个类型真正的类
toString() # 有时候对象打印出来,不是我们想看到的样子--》会打印toString的返回值
# python 中的 __str__
# 重写这个方法,实现打印对象时,显示长某个样子
equals() # 比较两个对象,是否相等---》重写equals实现让两个对象能比较
*/
获取Object类型变量的具体类型
public class Demo01 {
// 获取变量具体类型
public static void main(String[] args) {
// 方式一:通过getClass
// Object o=10;
Object o=new Animal();
System.out.println(o.getClass()); // class java.lang.Integer class Animal
// 方式二:通过判断 instanceof
Object o2=100;
if (o2 instanceof Animal){
System.out.println("o2是Integer类型");
Animal i=(Animal)o2;
System.out.println(i);
}
}
}
class Animal{}
容器类型之List
-
List是一个接口,接口下面有两个常见的类型(目的是可以存放动态的多个数据)
- ArrayList,连续的内存地址的存储(底层基于数组,内部自动扩容)
- LinkedList,底层基于链表实现(底层基于链表)
-
他俩用起来几乎一样,只是效率上有差距
基本使用
import java.util.ArrayList;
import java.util.LinkedList;
public class Demo01 {
// List :ArrayList LinkedList
public static void main(String[] args) {
// 1 ArrayList
// ArrayList ll =new ArrayList(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ArrayList<String> ll =new ArrayList<String>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ArrayList<Object> ll =new ArrayList<Object>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ll.add("justin");
// ll.add(19);
// ll.add("xx");
// System.out.println(ll);
// 1 LinkedList
// LinkedList ll =new LinkedList(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// LinkedList<String> ll =new LinkedList<String>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
LinkedList<Object> ll =new LinkedList<Object>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
ll.add("justin");
ll.add(19);
ll.add("xx");
System.out.println(ll);
}
}
常用方法
import java.util.ArrayList;
import java.util.LinkedList;
public class Demo07 {
// List :ArrayList LinkedList
public static void main(String[] args) {
// 1 ArrayList
// ArrayList ll =new ArrayList(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ArrayList<String> ll =new ArrayList<String>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ArrayList<Object> ll =new ArrayList<Object>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ll.add("justin");
// ll.add(19);
// ll.add("xx");
// System.out.println(ll);
// 2 LinkedList
// LinkedList ll =new LinkedList(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// LinkedList<String> ll =new LinkedList<String>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// LinkedList<Object> ll =new LinkedList<Object>(); // ll 要放很多元素,元素类型是什么? 没指定就可以放任意类型
// ll.add("justin");
// ll.add(19);
// ll.add("xx");
// System.out.println(ll);
// // 1 ArrayList 常用方法
// ArrayList<String> names = new ArrayList<String>();
// names.add("彭于晏");
// names.add("古天乐");
// names.add("杨颖");
// // names.add(19); //不能放数字
// names.add("刘亦菲");
//
// // 1 根据索引取值
// String name = names.get(1);
// System.out.println(name);
//
// // 2 修改某个位置值
// names.set(1, "迪丽热巴");
// System.out.println(names);
//
// // 4 大小
// System.out.println(names.size());
//
// // 5 是否包含
// System.out.println(names.contains("刘亦菲"));
//
// // 6 循环
// // 基于索引的循环
// for (int i = 0; i < names.size(); i++) {
// System.out.println(names.get(i));
// }
//
// // 基于迭代的循环
// for (String item:names) {
// System.out.println(item);
// }
// 4 LinkedList 常用方法
LinkedList<String> names = new LinkedList<String>();
names.add("彭于晏");
names.add("古天乐");
names.add("杨颖");
// names.add(19); //不能放数字
names.add("刘亦菲");
// 1 根据索引取值
String name = names.get(1);
System.out.println(name);
// 2 修改某个位置值
names.set(1, "迪丽热巴");
System.out.println(names);
// 4 大小
System.out.println(names.size());
// 5 是否包含
System.out.println(names.contains("刘亦菲"));
// 6 循环
// 基于索引的循环
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}
// 基于迭代的循环
for (String item:names) {
System.out.println(item);
}
// --------多的------
// 7 删除中间某个位置的值:可以按名字,可以按索引
names.remove("迪丽热巴");
names.remove(0);
// 8 在头部追加元素
names.addFirst("justin");
// 9 在尾部追加元素
names.addLast("justin");
System.out.println(names);
}
}
容器类型之Set
Set是一个接口,常见实现这个接口的有两个类,用于实现不重复的多元素集合。(用的少)
- HashSet,去重,无序。
- TreeSet,去重,内部默认排序(ascii、unicode)【不同的数据类型,无法进行比较】。
基本使用
// HashSet h = new HashSet();
HashSet<String> h = new HashSet<String>();
// 1 基本使用
h.add("刘亦菲");
h.add("刘亦菲");
h.add("迪丽热巴");
h.add("古天乐");
h.add("彭于晏");
h.add("Justin");
System.out.println(h);
// 2 判断值是否存在
System.out.println(h.contains("迪丽热巴"));
// 3 删除元素
h.remove("刘亦菲");
System.out.println(h);
// 4 长度
System.out.println(h.size());
// TreeSet使用,自动排序
TreeSet<String> h = new TreeSet<String>();
// 1 基本使用
h.add("刘亦菲");
h.add("刘亦菲");
h.add("迪丽热巴");
h.add("古天乐");
h.add("彭于晏");
h.add("Justin");
System.out.println(h);
// 2 判断值是否存在
System.out.println(h.contains("迪丽热巴"));
// 3 删除元素
h.remove("刘亦菲");
System.out.println(h);
// 4 长度
System.out.println(h.size());
// 5 循环
HashSet<String> h1 = new HashSet<String>();
h1.add("古天乐");
h1.add("彭于晏");
h1.add("Justin");
//for 循环
for(String item : h1){
System.out.println(item);
}
// while循环
Iterator i=h1.iterator();
while (i.hasNext()){
System.out.println(i.next());
}
交叉并集
HashSet<String> h1 = new HashSet<String>();
h1.add("古天乐");
h1.add("彭于晏");
h1.add("Justin");
HashSet<String> h2 = new HashSet<String>();
h2.add("古力娜扎");
h2.add("杨颖");
h2.add("迪丽热巴");
h2.add("刘亦菲");
h2.add("Justin");
HashSet<String> h3 = new HashSet<String>();
h3.addAll(h2); // 把h2的所有数据增加到h3中
System.out.println(h3);
h3.retainAll(h1); // 交集 & [Justin]
System.out.println(h3);
h2.addAll(h1); // 并集 | [杨颖, 迪丽热巴, 古力娜扎, 刘亦菲, Justin, 古天乐, 彭于晏]
System.out.println(h2);
h2.removeAll(h1); // 差集 [杨颖, 迪丽热巴, 古力娜扎, 刘亦菲]
System.out.println(h2);
容器类型之Map
Map是一个接口,常见实现这个接口的有两个类,用于存储键值对。–Python中的字典
- HashMap,无序。 (python3.6 以下)
- TreeMap,默认根据key排序。(常用)(python3.6 以上)
基本使用
HashMap hm = new HashMap();
hm.put("name", "lyf");
hm.put("age", 19);
hm.put("hobby", "篮球");
System.out.println(hm);
HashMap<String,String> hm = new HashMap<String,String>();
hm.put("name", "lyf");
hm.put("age", "19");
hm.put("hobby", "篮球");
System.out.println(hm);
//##### 2 TreeMap基本使用--会排序
TreeMap<String,String> hm = new TreeMap<String,String>();
hm.put("name", "lyf");
hm.put("age", "19");
hm.put("hobby", "篮球");
System.out.println(hm);
常用操作
//##### 3 HashMap --- TreeMap常用方法
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("name", "lyf"); // 反编译搜索 经常搜 : put("password
hm.put("age", "19");
hm.put("hobby", "篮球");
System.out.println(hm);
// 1 移除元素
hm.remove("name");
System.out.println(hm);
// 2 大小
System.out.println(hm.size());
// 3 获取值
System.out.println(hm.get("name"));
// 4 包含
System.out.println(hm.containsKey("name"));
System.out.println(hm.containsValue("篮球"));
// 5 替换
hm.replace("age", "99");
System.out.println(hm);
//##### 6 循环--》记住--》后面会看到
// 6.1 循环出key
for (String key : hm.keySet()) {
System.out.println(key);
System.out.println(hm.get(key));
}
// 6.2 了解:循环出value
for (String value : hm.values()) {
System.out.println(value);
}
// 6.3 循环出key和value--会遇到
for (Map.Entry<String, String> item : hm.entrySet()) {
System.out.println(item);
System.out.println(item.getKey());
System.out.println(item.getValue()); // sb.appendd(item.getKey())
}
// 6.4 c语言写法,很少见
Set s2 = hm.entrySet();
Iterator it2 = s2.iterator();
while (it2.hasNext()) {
Map.Entry entry = (Map.Entry) it2.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
System.out.println(k);
System.out.println(v);
}
面向对象
Java是完全的面向对象语言,没有函数,只有类,和在类中写的 方法。这里就不细说面向对象的理论了
public class Demo11 {
public static void main(String[] args) {
// 实例化得到猫对象
Cat cat1=new Cat();
Cat cat2=new Cat();
cat2.speak();
cat1.speak();
}
}
class Cat{
//定义一个mao类
public void speak(){
//写了一个speak方法
System.out.println("猫叫");
}
}
类的定义规范
// []内可以省略,|表示或单两个关键字不能同时出现
[public] [abstract|final] class 类名class_name [extends 继承的类名] [implements 实现的接口名] {
// 定义成员属性,给对象用
属性类型1 属性名1; // String name;
属性类型2 属性名2; // int age;
// 定义静态属性(类属性)
static 属性类型3 属性名3;
// 定义成员方法,给对象用
public int add(int a,int b){
return a+b;
}
// 定义静态方法(类方法)
public static void speak(){
System.out.println("说话");
}
}
// class Person{}
// public class Person{}
// abstract class Person{}
// final class Person{}
// public final class Person{}
// public final class Person exends Animal{}
// public final class Person exends Animal implements XXX{}
// 解释
public :表示 共有 的意思。如果使用 public 修饰,则可以被其他类和程序访问。每个 Java 程序的主类都必须是 public 类,作为公共工具供其他类和程序使用的类应定义为 public 类
abstract :类被 abstract 修饰,则该类为抽象类,抽象类不能被实例化,但抽象类中可以有抽象方法(使用 abstract 修饰的方法)和具体方法(没有使用 abstract 修饰的方法)。继承该抽象类的所有子类都必须实现该抽象类中的所有抽象方法(除非子类也是抽象类)
final :如果类被 final 修饰,则不允许被继承
class :声明类的关键字
class_name :类的名称
extends :表示继承其他类
implements :表示实现某些接口
demo
public class Demo01 {
// 类的定义规范
public static void main(String[] args) {
}
}
abstract class Animal{
abstract void speak();
public void run(){
System.out.println("走路");
}
}
interface XX{
}
class Person extends Animal implements XX {
@Override
void speak() {
}
}
类属性
// 语法
[public|protected|private] [static][final] <变量类型> <变量名>
// 解释
public protected private :用于表示成员变量的访问权限
static :表示该成员变量为类变量,也称为静态变量
final :表示将该成员变量声明为常量,其值无法更改
变量类型 :表示变量的类型
变量名:表示变量名称
class Person {
public String name;
private int age;
public static String school;
private static final String hobby="烫头"; // 类属性,常量
// 对象方法
public boolean isBoy(){
if(this.gender){
return true;
}else {
return false;
}
}
//类方法,输出学校
public static void getSchool(){
System.out.println(school);
}
}
成员方法
// 语法
[public|private|protected] [final][abstract] [static] <void|return_type><方法名>([参数]) {
// 方法体
}
// 解释
public private protected :表示成员方法的访问权限
static :表示限定该成员方法为静态方法--给类用的
final :表示限定该成员方法不能被重写或重载
abstract :表示限定该成员方法为抽象方法。抽象方法不提供具体的实现,并且所属类型必须为抽象类
class Person {
// 对象属性
public String name;
public boolean gender; // true 是男,false 是女
//类属性
public static String school="清华大学";
// 对象方法--Python 中定义在类中的方法
public boolean isBoy(){
if(this.gender){ // python中self
return true;
}else {
return false;
}
}
//类方法,输出学校
public final static void getSchool(){ // static 表示python中被@classmethod修饰的
System.out.println(school);
}
}
// python 中
class Person:
def speak(self):
print(self.name,'说话了')
@classmethod
def printSchool(cls):
print('北京大学')
p=Person()
p.speak() // 对象调用对象的方法
Person.printSchool() // 类来调用类的方法
构造方法
和python 中双下init 方法作用一样,java中的构造方法,与类同名,没有返回值,不需要void关键字,可以有多个
public class Demo02 {
// 类的构造方法
public static void main(String[] args) {
// 1 实例化得到条狗
Dog dog =new Dog();// 使用无参构造,实例化得到对象
System.out.println(dog.name);
Dog dog1 =new Dog("狗崽子",5);// 使用有参构造,实例化得到对象
System.out.println(dog1.name);
}
}
class Dog {
public String name;
public int age;
// 构造方法1,无参构造
public Dog() {
}
// 构造方法2 ,有参构造
public Dog(String n, int a) {
// this代指当前的对象
this.name = n;
this.age = a;
}
}
this关键字
this,等同于python 中的self
public class Demo03 {
// this关键字
public static void main(String[] args) {
Cat cat =new Cat("小野猫");
System.out.println(cat.age); // 0
System.out.println(cat.name); // 小野猫
System.out.println(cat.getAge());
Cat cat1 =new Cat("小家猫");
System.out.println(cat1.age); // 0
System.out.println(cat1.name); // 小家猫
cat1.age=2;
System.out.println(cat1.getAge());
}
}
class Cat{
public String name;
public int age;
public Cat(String name){
// this代指当前对象,this.name 拿到的是对象中的name属性
this.name=name;
this.age=0;
}
// 对象方法 返回猫年龄+10
public int getAge(){
return this.age+10;
}
// 如果方法,定义成static,方法中是没有this的
public static void DD(){ // 给类用的方法,没有对象
// System.out.println(this.name); // 报错
}
}
访问控制修饰符
无论在属性上,还是在方法上,都有个权限修饰符
public private protected 或 不写(friendly)
访问范围 | private | friendly(默认) | protected | public |
---|---|---|---|---|
同一个类 | 可访问 | 可访问 | 可访问 | 可访问 |
同一包中的其他类 | 不可访问 | 可访问 | 可访问 | 可访问 |
不同包中的子类 | 不可访问 | 不可访问 | 可访问 | 可访问 |
不同包中的非子类 | 不可访问 | 不可访问 | 不可访问 | 可访问 |
//1 private
用 private 修饰的类成员,只能被该类自身的方法访问和修改,而不能被任何其他类(包括该类的子类)访问和引用。因此,private 修饰符具有最高的保护级别
//2 friendly(默认)
如果一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定,该类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,即使其他包中有该类的子类。这种访问特性又称为包访问性(package private)
//3 protected
用保护访问控制符 protected 修饰的类成员可以被三种类所访问:该类自身、与它在同一个包中的其他类以及在其他包中的该类的子类。使用 protected 修饰符的主要作用,是允许其他包中它的子类来访问父类的特定属性和方法,否则可以使用默认访问控制符。
//4 public
当一个类被声明为 public 时,它就具有了被其他包中的类访问的可能性,只要包中的其他类在程序中使用 import 语句引入 public 类,就可以访问和引用这个类
静态变量和静态方法
static 修饰的属性或方法,都叫静态:【静态变量,静态属性】 【静态方法】 给类使用的
public class Demo04 {
// 静态属性或方法
public static void main(String[] args) {
// 1 实例化得到一个人对象
Person1 p1=new Person1();
p1.name="justin";
p1.showName(); // 对象调用
Person1.showSchool();//类调用,类方法
System.out.println(Person1.school); //类调用,类属性
// p1.school 当对象中没有school,但是类中有,也会拿到
System.out.println(p1.school);
// Person1.name 但是类中没有的不能去拿对象里面的
}
}
class Person1 {
public String name;
public static String school = "清华大学";
public void showName() {
System.out.println(this.name);
}
public static void showSchool() {
System.out.println(school);
}
}
面向对象之继承
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
// Java中的继承,只支持单继承,不支持多继承,但支持实现多个接口 python 可以继承多个类
class 父类 {
}
class 子类 extends 父类 {
}
class 子子类 extends 子类 {
}
构造方法
// 1 子类如果没写构造方法,默认使用父类无参构造
public class Demo06 {
// 继承关系下的构造函数
public static void main(String[] args) {
//实例化得到Boo
Boo b=new Boo();//Boo没有写构造方法,会调用父类的无参构造--》无参构造,name是没有传名字
System.out.println(b.name);
}
}
class Aoo{
public String name;
public Aoo(){
this.name="没有传名字";
}
public Aoo(String name){
this.name=name;
}
}
class Boo extends Aoo{
}
// 子类如果没写构造方法,不会自动使用父类的有参构造
public class Demo06 {
// 继承关系下的构造函数
public static void main(String[] args) {
//实例化得到Boo
// Boo b=new Boo();//Boo没有写构造方法,会调用父类的无参构造--》无参构造,name是没有传名字
// Boo b=new Boo("justin");//Boo没有写构造方法,不会调用父类的有参构造
Boo b=new Boo();//Boo没有写构造方法,不会调用父类的有参构造
System.out.println(b.name);
b.speak();
}
}
class Aoo{
public String name;
public Aoo(){
this.name="没有传名字";
}
public Aoo(String name){
this.name=name;
}
public void speak(){
System.out.println("说话了");
}
}
class Boo extends Aoo{
}
super与this关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
this关键字:指向自己的引用
public class Demo06 {
// 继承关系下的构造函数
public static void main(String[] args) {
//实例化得到Boo
// Boo b=new Boo();//Boo没有写构造方法,会调用父类的无参构造--》无参构造,name是没有传名字
// Boo b=new Boo("justin");//Boo没有写构造方法,不会调用父类的有参构造
Boo b=new Boo();//Boo没有写构造方法,不会调用父类的有参构造
System.out.println(b.name);
b.speak();
}
}
class Aoo{
public String name;
public Aoo(){
this.name="没有传名字";
}
public Aoo(String name){
this.name=name;
}
public void speak(){
System.out.println("说话了");
}
}
class Boo extends Aoo{
public void speak(){
System.out.println("asdfasdf");
}
public void PaoXiao(){
// 在这里,要调用父类的speak
// this.speak(); // 这样能调用到,因为自己没有,就会调用父亲
super.speak(); // 这样能调用到,因为直接调用父亲
// 他俩的区别是,
// this是先从自己找,自己找不到,再去父亲找
//super 是直接去找父亲
}
}
重写与重载
- 重写(Override)是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写
- 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同,被重载的方法必须改变参数列表(参数个数或类型不一样)
public class Demo07 {
//重写和重载
public static void main(String[] args) {
Coo c=new Coo();
c.speak();
c.speak("sdf");
}
}
// 重载--》不需要有继承关系
class Coo{
// 在类内部,可以定义两个同名的方法,但是一定要保证参数或返回值要不一样
// speak这个方法叫重载的方法
public void speak(){
System.out.println("coo说话了");
}
public void speak(String name){
System.out.printf("coo说话了--%s\n",name);
}
}
// 重写--》必须在继承关系下--》重写父类的方法--》但是参数和返回值必须保持一致才叫重写
class Doo{
public void speak(){
System.out.println("doo说话了");
}
}
class Eoo extends Doo{
@Override // 重写
public void speak() {
super.speak();
System.out.println("加入自己的功能");
}
// 能不能再写个重载的speak? 能
public void speak(String name){
System.out.println("重载了speak");
}
}
面向对象之接口
- 接口(Interface),它是一系列方法的集合,接口中定义了很多方法
- 接口不是类,用Interface声明
- 接口无法被实例化,只用来实现(类来实现接口)
- 一个类实现某个接口,必须实现这个接口中的所有方法
补充: java 中的Interface 和 go 中的 Interface,基本上用途一致,都可以通过Interface 来实现面向对象的三大特性
接口的定义
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
demo
public class Demo008 {
// 接口
public static void main(String[] args) {
}
}
// 接口规范子类的行为
// 为了多态
interface Duck{
// 走路方法
public void run();
//说话方法
public void speak();
}
class PDuck implements Duck{
@Override
public void run() {
}
@Override
public void speak() {
}
}
接口继承
// Hobby接口
interface Hobby{
public void run();
}
// Duck接口继承了Hobby--》相当于在Duck中写了run方法
interface Duck extends Hobby{
// 走路方法
//说话方法
public void speak();
}
接口实现
public class Demo008 {
// 接口
public static void main(String[] args) {
// Duck duck=new Duck(); //接口不能被实例化
//多态
// Duck duck=new PDuck();
// Duck duck1=new DDuck();
// 只能用到接口中的方法
PDuck pduck=new PDuck();
// runPDuckSpeak(pduck);
duckSpeak(pduck);
DDuck dduck=new DDuck();
// runDDuckSpeak(dduck);
duckSpeak(dduck);
}
// public static void runPDuckSpeak(PDuck p){
// p.speak();
//
// }
// public static void runDDuckSpeak(DDuck d){
// d.speak();
// }
public static void duckSpeak(Duck d){
d.speak();
}
}
// 接口规范子类的行为
interface Hobby{
public void run();
}
// 为了多态
interface Duck extends Hobby{
// 走路方法
//说话方法
public void speak();
}
class PDuck implements Duck{
@Override
public void run() {
}
@Override
public void speak() {
}
}
class DDuck implements Duck{
@Override
public void run() {
}
@Override
public void speak() {
}
public void eat(){
}
}
面向对象之抽象类
public class Demo09 {
// 抽象类
public static void main(String[] args) {
}
}
// 定义一个类,类中方法必须有实现
// 定义一个接口,接口中的方法不能有实现
abstract class Foo {
public abstract void speak();
public void run() {
System.out.println("走路");
}
}
class Zoo extends Foo{
@Override
public void speak() {
}
}
面向对象之封装
// java中一般不直接通过对象调用属性,而是通过方法来设置和获取属性【更安全】
public class Demo10 {
//封装
public static void main(String[] args) {
//java中一般不直接通过对象调用属性,而是通过方法来设置和获取属性【更安全】
Yoo y=new Yoo();
// y.name="justin";
// y.age=199999;
y.setName("justin");
y.getName();
}
}
class Yoo{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
}
面向对象之多态
多态是同一类事物[实例,对象]多种形态,从而调用同一类[实例,对象]方法时,表现出不同情况和返回不同的数据
通过类继承实现多态
public class Demo11 {
public static void main(String[] args) {
// 人是人,狗是狗,猫是猫
Person2 p=new Person2();
Dog1 d=new Dog1();
Cat1 c=new Cat1();
// 但是我们是同一类
Animal1 animal1;
animal1=d;
animal1=c;
animal1=p;
// animal1.eat();
Demoo(c);
}
public static void Demoo(Animal1 p){
p.eat();
}
}
class Animal1{
public void eat(){
System.out.println("动物吃饭");
}
}
class Dog1 extends Animal1{
public void eat(){
System.out.println("狗吃饭");
}
}
class Cat1 extends Animal1{
public void eat(){
System.out.println("猫吃饭");
}
}
class Person2 extends Animal1{
public void eat(){
System.out.println("人吃饭");
}
public void speak(){
System.out.println("人说话");
}
}
通过接口实现多态
public class Demo12 {
public static void main(String[] args) {
// 通过接口实现多态
// 人是人,狗是狗,猫是猫
Person3 p=new Person3();
Dog2 d=new Dog2();
Cat2 c=new Cat2();
// 但是我们是同一类
Animal3 animal1; //接口类型,不能被new
animal1=d;
animal1=c;
animal1=p;
Demoo(c);
}
public static void Demoo(Animal3 p){
p.eat();
}
}
interface Animal3{
public void eat();
}
class Dog2 implements Animal3{
public void eat(){
System.out.println("狗吃饭");
}
}
class Cat2 implements Animal3{
public void eat(){
System.out.println("猫吃饭");
}
}
class Person3 implements Animal3{
public void eat(){
System.out.println("人吃饭");
}
public void speak(){
System.out.println("人说话");
}
}
Java 中包
为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
- 在同一个包下,不能出现相同类名
- 在不同包下,可以有同名的类
包的作用
- 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用
- 同文件夹一样,包采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
- 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
// 右键,新建包----》其实就是文件夹
com.justin
// 在包中定义类
com.justin
Db.java
Helper.java
// Helper.javaa
package com.justin;
public class Helper {
public int add(int a ,int b){
return a+b;
}
}
// Db.java
package com.justin;
public class Db {
public String addNb(String s){
return s+"_NB";
}
}
引入包使用
import com.justin.Db;
import com.justin.Helper;
// import com.justin.*;
public class Demo13 {
public static void main(String[] args) {
// 使用包
// 调用add ,完成我们的操作
int res=Helper.add(3,4);
System.out.println(res);
// 使用 justin 包下 Db+nb方法
Db db=new Db();
System.out.println(db.addNb("justin"));
// 用lqz包下 Db的showName方法
com.lqz.Db db1=new com.lqz.Db();
db1.showName();
}
}