方法的形式参数问题是引用类型和基本类型的区别.
基本数据类型:形式参数改变对实际参数没有影响.(传递的是具体数值)
引用类型(数组,类,接口): 形式参数的改变对实际参数有影响(传递的是地址),需要传递是当前类的具体类对象.
权限修饰符
- 权限修饰符,是java中的一些关键字,用于决定代码在哪里可以被访问哪里不能被访问的关键字
- 所有的权限,都是封装的体现,只是范围不同罢了
- 范围: private 最小,其次默认修饰符,然后protected受保护的,最大为public.
- 权限修饰符
方法的形式参数是引用类型,具体类 的情况,实际参数如何传递?
方法的形式参数是引用类型的时候:
具体类:调用方法的时候,实际参数需要这个类的具体对象 .
抽象类:调用方法的时候,实际参数需要传递抽象类的子类对象.
接口:调用方法的时候,实际参数需要传递接口的子实现类对象.
方法返回值类型是一个具体类,如何返回?
方法返回值类型是一个具体类:
抽象类: 需要返回的是该抽象类的子类对象.
接口:需要返回的是当前接口的子实现对象.
具体类:需要返回的值是具体类,需要返回的是该具体类的对象.
package com.qf.innertest;
/**
* 方法的返回值问题:
* 如果是接口类型,方法结束,必须要返回接口的子实现类对象
*/
interface CanCry{
void voice();
}
//返回接口的子实现类对象
//接口多态
class CryDemo{
public CanCry faction(){
return new CanCry() {
@Override
public void voice() {
System.out.println("狗 汪汪汪");
}
};
}
}
class Dog implements CanCry{
@Override
public void voice() {
}
}
public class inner_1 {
public static void main(String[] args) {
CryDemo cryDemo = new CryDemo();
CanCry canCry = cryDemo.faction();
canCry.voice();
}
}
内部类
- 定义在类的内部的类,就是内部类。和方法、变量等,均作为类的成员。
1.普通成员内部类
- 定义在类成员位置的类,就是成员内部类
- 格式
class 外部类类名 {
外部类成员
class 内部类类名 {
内部类成员
}
}
成员内部类的说明:
- 内部类可以直接访问外部类中所有的成员
- 外部类中,不能直接访问内部类的成员,必须通过在外部类中创建内部类的对象,才可访问
- 在外部类以外访问内部类的成员,可以创建外部类对象,对象调用外部类方法,方法中通过内部类对象访问内部类成员,从而达成间接访问
- 在外部类以外访问内部类的成员,可以直接创建内部类对象:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
class A{
private int i =10;
class B{//内部类
public void show(){//成员方法
System.out.println(i);
}
}
public void method(){
B b =new B();
b.show();
}
}
public class Test {
public static void main(String[] args) {
Outer2 outer2 = new Outer2();
outer2.method();
}
}
私有成员内部类
- 普通成员内部类的声明上加上private关键字
- 格式:
class 外部类类名 {
外部类成员
private class 内部类类名 {
内部类成员
}
}
私有成员内部类的说明:
- 在私有成员内部类中,可以访问所在外部类的所有成员
- 在外部类中,要通过内部类对象访问内部类成员
- 在外部类以外,只能通过间接方式访问私有成员内部类的内容。没有任何的直接访问方式。因为对于外部类而言,私有成员内部类也是一个私有成员,所以在外界无法直接访问。
静态成员内部类
- 格式:
class 外部类类名 {
外部类成员
static class 内部类类名 {
内部类成员
}
}
- 访问特点:
- 静态成员内部类是外部类的静态成员
- 在静态成员内部类中,访问外部类成员,外部类成员如果是静态的就按照静态访问,非静态就按照非静态访问
- 在外部类中,访问静态成员内部类的内容,也要按照静态按照静态访问,非静态按照非静态访问
- 总结:访问的内容,到底用静态方式还是非静态方式,不取决于类本身是否为静态,而是取决于要访问的内容本身是静态还是非静态
- 在外部类以外创建静态成员内部类的格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
局部内部类
- 局部内部类:定义在方法中的类
- 访问说明:方法中的局部变量在方法外不能被访问,局部内部类与局部变量同作为方法中的成员,也在方法外不能被访问。所以局部内部类在方法以外没有任何手段内被访问。
- 解决方式:只能执行局部内部类所在方法,在方法中创建局部内部类对象,对象调用类中方法,一并执行.
class Outer{
private int x = 100 ;
public void show(){
int num = 20 ;
class Inner{
public void method(){
System.out.println(x);
System.out.println(num)
}
}
Inner inner = new Inner() ;
inner.method();
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer outer = new Outer() ;
outer.show();
}
}
匿名内部类:
- 没有名字的内部类
- 使用场景:
- 实现抽象类
- 实现接口
- 格式:
new 抽象父类名称或接口名称() {
要实现的抽象方法
};
- 本质:
- 匿名内部类本质上是一个实现类对象 继承了该类(抽象类),或者实现了接口的子类对象.
- 编译过后会形成一个类文件.
interface Love{
void show() ;
}
class Outer2{
public void method(){
Love l = new Love(){
@Override
public void show() {
System.out.println("show Love");
}
} ;
l.show();
}
}
public class Test {
public static void main(String[] args) {
Outer2 outer2 = new Outer2() ;
outer2.method();
}
}
5.方法
1.toString方法
- getClass() 获取到当前对象所属的类型
- hashCode() 根据对象的情况,计算出对象的哈希码值
- toString() 返回对象的字符串表示形式
2.equals方法
- 比较两个对象是否相等。这两个对象分别为:调用者对象,参数对象
- 在Object类型中,比较的是两个对象的地址值是否一致.
比较对象的属性值来判断对象是否相等,我们就需要在对象所属类型中重写equals方法3
3. ==和equals的区别
- 共同点:都是用于比较数据是否相等的方式
- 不同点:
- ==是运算符,equals是方法
- 比较的内容不同:==既可以基本数据类型,也可以比较引用数据类型;equals只能比较引用数据类型
- 比较规则不同:==比较基本数据类型,比较值,比较引用数据类型,比较地址;equals重写前比较地址,重写后比较值
package com.qf;
/*
键盘录入字符串,判断该字符串是否是对称字符串 (功能改进)
StringBuffer完成
*/
import java.util.Scanner;
/*判断输入的字符是不是对称字符串*/
public class Symmetry {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String a = sc.nextLine();
StringBuffer sb = new StringBuffer(a); //StringBuffer调用方法reverse反转.
sb.reverse();
String str = new String(sb) ;
if(str.equals(a)){
System.out.println("该字符串是对称字符串");
}else{
System.out.println("该字符串不是对称字符串");
}
}
}
String类型
String类型表示字符串
- 字符串字面值常量,存储在方法区的常量池中
- String类型表示的字符串本身是一个常量,创建后就无法修改(不可变字符序列)
- 不可变的原因:String没有提供任何的set方法能够修改字符串本身.
构造方法
- String() 创建一个空字符.
- isEmpty() 判断调用者是否为空串
length() 返回调用者字符串的长度
charAt(int index) 从调用者字符串上获取到指定索引的字符并返回
String类型的转换功能.
- byte[] getBytes() 将调用者字符串转为byte数组
- char[] toCharArray() 将调用者字符串转为对应的字符数组
- toUpperCase() 将字符串转为纯大写
- toLowerCase() 将字符串转为纯小写
- concat(String str) 将参数字符串追加到调用者字符串之后(拼串)
- ValueOf重载:都是静态方法,用于将其他数据类型转换为String类型.
System类
- 用于描述系统资源的类型,不能创建对象。类中的方法都是静态的,使用类名直接调用
- 常用字段:
- System.out标准输出流,默认关联显示器
- System.in 标准输入流,默认关联键盘
- System.err 错误打印流,默认关联到显示器,用于打印错误信息
- 常用方法:
- gc() 运行垃圾回收器
- currentTimeMillis() 获取时间的毫秒值。1000ms = 1s.
StringBuilder类
- StringBuffer是一个可变字符序列。因为在类中,提供了修改字符串的成员方法,常用方法是append和insert,就是在StringBuffer本身上,进行修改操作。
String和StringBuffer的区别:
- String本身长度不可变,StringBuffer长度可变,通常我们将StringBuffer当做一个长度可变的容器,用于存储字符.
构造方法
- 构造方法的作用:创建当前对象,将其他数据转换为当前类型
StringBuffer() 创建一个字符串生成器.
添加功能
- append(任意类型)
- 作用:将任意类型的参数追加到当前可变字符序列之后
- 底层操作:将当前字符个数和当前数组容积进行比较,如果溢出,就做数组拷贝,将原数组的内容添加到新数组中,其中,新数组的容积是原数组容积<<1+2。所以,数组自动增大实际上是数组的拷贝.
- insert(int index, 任意数据类型) 可以将任意数据类型插入到指定位置
替换和反转功能
- replace(int start, int end, String str) 使用指定字符串去替换字符串缓冲区中指定的子串
- reverse() 反转字符串缓冲区.
package com.qf.homework;
/* 编写一个程序,将下面的一段文本中的各个单词的字母顺序翻转
"To be or not to be",将变成"oT eb ro ton ot eb"。
为什么要类型转换?
*/
import java.util.Scanner;
public class reverse {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String a = sc.nextLine();
String [] ss = a.split(" "); //按照空格切割字符串---->字符串数组
/* String类是字符串常量,是不可更改的常量。
而String Buffer是字符串变量,他的对象时可以扩充和修改的。*/
for (int i = 0; i < ss.length; i++) { //遍历
StringBuffer sb = new StringBuffer(ss[i]); //单个的单词字符串数组
sb.reverse(); //空格分开然后反转
String str = new String(sb) ; //
System.out.print(str.concat(" "));
}
}
}
基本数据类型包装类
Integer类型
- 提供了在int、Integer、String之间相互转化的功能
Character类
构造方法:Character(char value) :将一个char类型的字符值构造成Character类对象.
成员方法:
判断字符是否为大写字母字符
public static boolean isUpperCase(char ch)
判断字符是否为小写字母字符
public static boolean isLowerCase(char ch)
判断字符是否为数字字符
public static boolean isDigit(char ch)
判断一段字符里边的大小写数字的个数.
public class Test {
public static void main(String[] args) {
int bigCount = 0 ;
int smallCount = 0 ;
int numberCount = 0 ;
Scanner sc = new Scanner(System.in) ;
System.out.println("请输入一个字符串:");
String line =sc.nextLine() ;
char[] chs = line.toCharArray();
for(int x = 0 ; x < chs.length ; x++){
char ch = chs[x] ;
if(Character.isUpperCase(ch)){
bigCount++ ;
}else if(Character.isLowerCase(ch)){
smallCount ++;
}else if(Character.isDigit(ch)){
numberCount++;
}else{
System.out.println("没有该字符");
}
}
System.out.println("大写字母字符共有:"+bigCount+"个");
System.out.println("小写字母字符共有:"+smallCount+"个");
System.out.println("数字字符共有:"+numberCount+"个");
}
}
Random类
构造方法:
Random() 创建对象之后,调用nextInt()/nextInt(int n):每次随机数数字不一样的
public Random(long seed) :调用nextInt()/nextInt(int n):每次随机数数字一样的
成员方法:
int nextInt():int类型的范围获取
int nextInt(int n):[0,n) :范围
package com.qf; import java.util.Random; import java.util.Scanner; /* random() 返回[0.0, 1.0)的随机数 */ /*根据int变量n的值来获取随机数字,范围是[1,n],可以取一也可以取n 预习Random类的nextInt(int n ):0-n 之前的随机数*/ public class RandomTest { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请控制随机数的大小"); int n = sc.nextInt(); //控制随机数的大小 System.out.println("请控制随机数的个数"); int b = sc.nextInt(); Random ran = new Random(); // Random类的nextInt方法提供随机数 for (int i = 0; i < b; i++) { //控制个数 //本来范围是[0,n),整体+1之后变成了[1,n+1),也就是[1,n] int result = ran.nextInt(n) + 1; System.out.println(result); } } }
自动拆装箱
- 装箱和拆箱
- 装箱:将基本数据类型,封装成包装类的对象,这个过程就是装箱。
- 拆箱:将包装类对象中的基本数据类型解析出来,就是拆箱。
- 自动拆装箱:
- 自动装箱:可以直接使用基本数据类型的数据,给引用数据类型赋值
- 自动拆箱:可以直接使用基本数据类型包装类的对象,给基本数据类型赋值,或者直接参与运算
Date类
该类的对象用于表示一个特定的瞬间,精确到毫秒值
getTime() 获取Date对象表示的时间的毫秒值
setTime(long time) 将调用者对象的毫秒值设置为指定值.
构造方法:
public Date():无参构造方法 :创建日期对象,获取当前系统时间的日期格式
:包含星期 年份 月份 月中的日期... (获取当前日期:使用这个)
public Date(long date):创建日期对象,和1970年1月1日时间有关系public SimpleDateFormat(String pattern)
yyyy:年 MM:月 dd:月中日期 HH:小时 mm:分钟 ss:秒
成员方法:
public long getTime():获取时间的毫秒值;
Date---->String public String foramt(Date date) :格式化
String--->Date: public Date parse(String dateStr) throws ParseException: 解析
这个本身可能出现异常,如果解析的字符串的格式和 pattern参数的模式匹配,就出错了,解析失败!
public SimpleDateFormat(String pattern)
package com.qf;
/*
*通过输入出生年月 求年龄
* */
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class BirthdayTest {
public static void main(String[] args) throws ParseException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入出生日期:");
String s = sc.nextLine();
Date birthdayDate = new SimpleDateFormat("yyyy-MM-dd").parse(s);
System.out.println(birthdayDate);
long oldTime = birthdayDate.getTime();//
//System.out.println(oldTime);
Date date = new Date();
long newTime = date.getTime();
long day = (newTime-oldTime)/1000/60/60/24;
long sui = (newTime-oldTime)/1000/60/60/24/365 ;
System.out.println("您今年"+sui+"岁"+",已经来到这个世界"+day+"天");
}
}
Collection类
1、定义
Collection<E></>父接口 代表所有的单列集合,只能存储一种引用类型的集合
两个子接口 List<E>/Set<E>
ArrayList:经常默认使用的集合(效率高)
基本功能:
boolean add(E e):添加任何类型元素 E---->理解为Object类型元素
boolean contains(Object o):判断集合中是否包含指定的元素
boolean isEmpty():判断集合是否为空
boolean remove(Object o):移出集合中的元素
void clear() :清空集合
int size():获取集合的元素数
Collection高级功能:
Object[] toArray() :将集合转换成对象数组
Iterator iterator() :Collection的专有遍历方式 (迭代器!)public class Test { public static void main(String[] args) { Collection c = new ArrayList() ; System.out.println(c.isEmpty()); System.out.println(c) ; c.add("hello") ; c.add(100) ; c.add('a') ; c.add("world") ; System.out.println(c); System.out.println(c.contains("hello")); System.out.println(c.contains("b")); System.out.println(c.size()); } }
迭代器
Iterator<E> iterator():迭代器
Iterator:
Object next()返回迭代中的下一个元素。 (返回任意java类型)
boolean hasNext():判断功能:判断迭代器中是否下一个元素
返回true,表示存在
返回false,不存在!
class Student {
private String name;
private int age;
private String sex;
public Student() {
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
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;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
public class Test {
public static void main(String[] args) {
Collection c =new ArrayList();
Student s1 =new Student("小一",10,"男");
Student s2 =new Student("小二",10,"女");
Student s3 =new Student("小三",10,"女");
Student s4 =new Student("小四",10,"男");
//Student s5 =new Student("小五",10,"男");
c.add(s1);
c.add(s2);
c.add(s3);
c.add(s4);
c.add(new Student("小五",10,"男"));
Iterator iterator = c.iterator();
while (iterator.hasNext()){
Object o = iterator.next();
System.out.println(o);
}
}
}
package com.qf.LinkedList;
import java.util.LinkedList;
/**
* 使用LinkedList的特有功能模拟栈结构特点?
* 栈结构:先进后出
*
* 相当于自定义一个类,这个类完成一些功能,需要使用到LinkedList集合的特有功能
* 这个功能添加元素(压栈)--->使用LinkedList的addFirst():每一次将元素添加到链表开头
* 获取元素:(弹栈)----->使用LinkedList集合的removeFist():相当于pop:弹栈,删除第一个并获取第一个元素
*/
public class MyStack {
//成员变量的位置
private LinkedList linkedList ;
//定义一个构造方法
public MyStack(){
//创建一个LinkedList集合对象
linkedList = new LinkedList() ;
}
//定义一个功能:添加元素的方法 压栈
public void addElement(Object obj){ //添加任何Java类型 "hello","world"
//间接用到LinkedList的特有功能
linkedList.addFirst(obj); // "world","hello"使用linkedList就添加开头了
}
//定义一个功能,弹栈: 取出元素 ,将LinkedList集合第一个元素删除并返回
public Object getElement(){
return linkedList.removeFirst() ;//删除第一个并返回
}
//提供判断功能
public boolean isEmpty(){
return linkedList.isEmpty() ;
}
}
List集合
1、集合特点
1)元素可以重复
2)存储和取出一致(有序性)
2、便利方式
1)普通for循环: 使用集合 int size():获取元素数
E get(int index):通过角标获取元素
2)集合的列表迭代器ListIterator listiterator()
ListIterator:
boolean hasNext():是否有下一个元素
E next():获取下一个元素public class Test { public static void main(String[] args) { List<String> list = new ArrayList<>() ; list.add("hello") ; list.add("world") ; list.add("javaEE") ; list.add("易烊千玺") ; Object[] objects = list.toArray(); for(int x = 0 ;x <objects.length ;x++){ String s = (String) objects[x]; System.out.println(s); } Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String s = iterator.next(); System.out.println(s); } for(int x= 0 ;x < list.size();x++){ String s = list.get(x); System.out.println(s); } ListIterator<String> lit = list.listIterator(); while(lit.hasNext()){ String s = lit.next(); System.out.println(s) ; } while(lit.hasPrevious()){ String s = lit.previous(); System.out.println(s); } for(String s:list){ System.out.println(s); } } }
package com.qf.LIstTest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListTest {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("王二", 25));
list.add(new Student("王三", 29));
list.add(new Student("王四", 28));
list.add(new Student("王五", 28));
list.add(new Student("王六", 28));
System.out.println("for");
for (Student s : list) {
System.out.println(s);
System.out.println("--------------");
}
System.out.println("list.size");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("list迭代器");
ListIterator<Student> it = list.listIterator();
while (it.hasNext()) {
Student s1 = (Student) it.next();
System.out.println(s1);
System.out.println("-----------------");
}
//反向遍历
System.out.println("反向遍历");
ListIterator it2 = list.listIterator();
while (it.hasPrevious()) {
Student student2 = (Student) it.previous();
System.out.println(student2);
}
}
}
选择排序法:
选择排序:即用数组的第一个元素与第二个第三个依次比较,直到与最后一个对比结束,将最小的数往前面放,然后是第二个元素和后面的元素进行对比,一直要对比数组长度次.
图解:
public class Test {
public static void main(String[] args) {
//创建一个数组,静态初始化
int[] arr = {24,69,87,56,13} ;
for(int x = 0 ; x < arr.length-1; x++){
for(int y = x+1; y < arr.length ; y++){
//元素比较,要进行判断,前面的元素和后面元素比较
if(arr[x] > arr[y]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
}
System.out.println("排序后:") ;
System.out.println(Arrays.toString(arr));
}
}
Vector集合
Vector集合底层数据结构数组,是List集合接口子实现类之一,遍历元素能够List的五种方式
特有功能 :
添加元素
public void addElement(E obj):添加任意元素 如果E类型确定了,就只能添加这个数据类型
类似于 集合的通用功能add(E obj)
遍历元素方式1
public Enumeration<E> elements():获取组件(返回值是枚举接口---产生一系列元素)
类似于Collection集合的Iterator iterator()迭代器
Enumeration枚举接口
boolean hasMoreElements() 判断是有更多的元素
--->类似于Iterator迭代器里面的hasNext()
E nextElement() :获取下个元素
--->类似于Iterator迭代器里面的next():获取下一个元素
遍历元素方式2
public E elementAt(int index)通过角标获取元素 ---类似于List集合的public E get(int index)
结合 int size()获取集合长度(集合元素数量)public class Test { public static void main(String[] args) { Vector<String> v = new Vector<>() ; v.addElement("hello"); v.addElement("world"); v.addElement("JavaEE"); v.addElement("蔡徐坤"); Enumeration<String> enumeration = v.elements(); while(enumeration.hasMoreElements()){ String s = enumeration.nextElement(); System.out.println(s); } for(int x = 0 ; x < v.size(); x++){ String s = v.elementAt(x); System.out.println(s); } for(String s:v){ System.out.println(s); } } }
LinkedList集合
底层数据结构是链表,链表的特点:查询慢(每次需要冲链表头查询到末尾),增删快;
特有功能:
public class Test {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<>() ;
link.addFirst("hello") ;
link.addFirst("world") ;
link.addFirst("java") ;
link.addLast("javaEE");
System.out.println(link) ;
String first = link.getFirst();
System.out.println(first) ;
String last = link.getLast();
System.out.println(last);
System.out.println(link.removeFirst());
System.out.println(link);
}
}
public void addFirst(E e):添加到链表的开头
public void addLast(E e):添加到链表的末尾
public E getFirst():获取链表的第一个元素
public E getLast():获取链表的末尾的元素
public E removeFirst():删除链表第一个元素
public E removeLast():删除链表的最后一个元素
public void push(E e):推送到链表开头(压栈)---等价于public void addFirst(E e):添加到链表的开头
public E pop():弹出最后一个元素(弹栈) 等于removeFirst() :将第一个元素删除并返回
Set集合
保证元素唯一,而且不能保证迭代次序唯一,无序性(元素不重复,不能保证顺序---哈希表(key-value键值对)完成的(桶状结构))
创建HashSet(Set接口的子实现类之一)集合对象来存储String类型,重复的数据,看效果为什么保证元素能唯一的:
HashSet底层依赖于Map<K,V>接口的子实现类HashMap<K,V>实现的
HashSet的add()方法依赖于HashMap的put 方法,这个方法间接依赖于Object类的equals和hashCode()
而现在存储String类型,String底层已经重写了hashCode()和equals方法
HashCode:比较字符串的哈希码值(理解为地址值)是否一样,如果一样,比较内容是否一样
英文可以,但是中文,繁写字体或简写字体,hashCode一样,内容可能不一样;必须重写equals,比较内容是否相容!
public class Test {
public static void main(String[] args) {
Set<String> set = new HashSet<>() ;
set.add("hello") ;
set.add("hello") ;
set.add("javaEE") ;
set.add("world") ;
set.add("world") ;
set.add("android") ;
set.add("android") ;
set.add("python") ;
set.add("python") ;
for(String s:set){
System.out.println(s) ;
}
}
}