内部类
- 一个类对应提供的内容仅仅是为某一个类单独服务
- 可以直接访问外部类的私有的成员变量
普通内部类
- 直接将一个类的定义放在另外一个类的类体中
格式
访问修饰符 class 外部类的类名 {
访问修饰符 class 内部类的类名 {
内部类的类体;
}
}
调用方法
外部类名 外部类实例名 = new 外部类名();
注意内部类和外部类及内部方法有同一个成员变量时,用就近原则方法参数,非要用外部类或内部类的成员,外部类则用:外部类.this.成员名,内部类:this.成员名
外部类名.内部类名 内部类实例名 = 外部类实例名.new 内部类名();
静态内部类
- 使用static修饰的内部类,属于类层级。
格式
访问修饰符 class 外部类的类名 {
访问修饰符 static class 内部类的类名 {
内部类的类体;
}
}
调用方式
外部类名.内部类名 内部类实例名 = new 外部类名.内部类名();
注意
- 静态内部类 不能直接访问==外部类==的==非静态成员==
- 静态内部类 可以==直接创建对象==
- 如果静态内部类访问==外部类==中与本类内==同名的成员变量或方法==时,需要使用
类名.
的方式访问 - 有static就是类层级,类名.调用
- 没有static就是对象层级,引用.调用
局部内部类
- 直接将一个类的定义放在方法体的内部
格式
访问修饰符 class 外部类的类名 {
访问修饰符 返回值类型 成员方法名(形参列表) {
class 内部类的类名 {
内部类的类体;
}
}
}
调用方式
方法内调用:
局部内部类类名 局部内部类实例名 = new 局部内部类类名();
局部内部类实例名.内部类方法名();
注意
- 局部内部类只能在方法的内部可以使用
- 局部内部类可以在方法体内部直接创建对应对象
匿名内部类:没听懂课程,无能为力
- 就是指没有名字的内部类
创建一个接口A,再创建一个实现接口的类B,再创建一个类C去调用,
String
- string不是八大基本类型,是引用类型,声明变量是引用变量,是引用char基本类型的合集;
- string可以用+连接,只要有一个string,则连接后都变成string
- 空格: \t \f \r
- equals 是比较两个字符串的内容是否相同,返回的是boolean值,相同就是true,不同就是false,不区分大小写
注意
-
不能使用
"=="
运算符比较两个字符串是否相等-
"=="
只能确定两个字符串是否指向同一个对象 - 不会比较字符串的内容是否相等
-
-
空串是长度为0的字符串
- 空串是一个
Java
对象,有自己的串长度0
和内容空
- 空串是一个
-
String
为null
,表示没有任何对象与该变量关联,跟空是不同的,空是没有长度的
常用的API方法
- contains(s1),boolean返回值
// 字符串中包含"ing",返回true
System.out.println(str.contains(“ing”)
包装类
万物皆对象,我们调用基本数据类型时,都是包装好的类,我们是直接创建了对应类的对象,然后调用对应的方法
int->Integer
错误与异常
Exception
JVM识别错误代码,并定位提示错误信息,在执行前拦截;
try…catch…finally-尽量用这个
作用:有异常,判断异常,程序还是能正常执行,不会被拦截不能执行,无论有没有错,finally里的是一定会执行的;
throw
谁调用谁处理
- 格式:
Error
不可预料,代码外的异常
集合:collection(单个) 、map(单对:key value)
概念
多个不同类型的对象数据
collection 接口是List queue set接口的父类接口
- 可以添加变量,对象
格式
add():集合中添加单个对象
Collection c1 = new ArrayList();
c1.add(new String("hello")); //放在堆区
System.out.println("c1:"+c1);
c1.add("zj"); //放在常量池
System.out.println("c1:"+c1);
c1.add(77);
System.out.println("c1:"+c1);
//c1.add(new Persion(name:"zhaojie",age:88)); //要是想打印出这种格式而不是地址,需要在新建对象的类里添加toString方法,基本八大类型add的时候能直接打印出来添加内容,是因为本身的类有toString方法
c1.add(new Persion("zhaojie",88));
System.out.println("c1:"+c1);
addAll():集合中添加多个元素
Collection c2 = new ArrayList();
c2.add(88);
c2.add("java");
c1.addAll(c2); //c1:[hello, zj, 77, Persion{name='zhaojie', age=88}, 88, java]
c1.add(c2); //c1:[hello, zj, 77, Persion{name='zhaojie', age=88}, [88, java]]
判断集合内容
contains():判断集合里有没有某个对象
`boolean b2 = c1.contains(“hello”);
System.out.println(“是否包含:”+b2);
可以直接判断int、string类型,如果要判断对象,则需要在呢这个对象对应的类里面添加equal()、hashCode方法;
containsAll():判断集合里有没有某个元素
集合删除
remove()
删除对象,需要用以下方式删除,注意:只要有一个符合被删除,就会返回true,不会提示
boolean b7 = c1.remove(new Persion("zhaojie",88);
System.out.println("remove 后的 c1:"+c1);
removeAll()删除集合的每个元素
集合的其他方法
集合转化成数组
c1.toArray().var回车
Object[] objects = c1.toArray();
数组转化成集合
集合-迭代器
概念
- java.util.Iterator接口
- 描述迭代器对象
- ==遍历Collection集合==中的所有对象
方法
方法声明 | 功能介绍 |
---|---|
boolean hasNext() | 判断集合中是否有可以迭代/访问的元素 |
E next() | 用于取出一个元素并指向下一个元素 |
void remove() | 用于删除访问到的最后一个元素 |
Iterator i1 = c1.iterator();
while(i1.hasNext()){
System.out.println(i1.next() );
}
toString加深打印效果
``System.out.println(c1);
// 由于上个循环已经使得迭代器走到了最后,因此需要重置迭代器
iterator = c1.iterator();
StringBuilder s = new StringBuilder();
s.append("[");
while (iterator.hasNext()){
Object next = iterator.next();
if(!iterator.hasNext()){
s.append(next).append("]");
}else {
// 否则拼接元素加逗号加空格
s.append(next).append(",").append(" ");
}
}
System.out.println(s);
删除
if(d.equals(next)){
c1.remove(next);
}
注意
- 在迭代过程中不能对集合/数组对象进行操作,否则会报==并发修改异常==
forEach:对数组或集合进行遍历
Collection c1 = new ArrayList();
c1.add("zhaojie");
c1.add(99);
System.out.println("c1:"+c1);
for (Object obj:c1
) {
System.out.println("foreach:"+obj);
}
list
-
List
集合的主要实现类有:ArrayList
类、LinkedList
类、Stack
类、Vector
类。-
ArrayList
类的底层是采用==动态数组==进行数据管理的,支持==下标访问==,==增删元素不方便==。 -
LinkedList
类的底层是采用==双向链表==进行数据管理的,==访问不方便==,==增删元素方便==。 -
Stack
类的底层是采用==动态数组==进行数据管理的,主要管理的是后进先出特征的数据结构,叫做栈 -
Vector
类是比ArrayList类更线程安全的类,但是效率比较低,已过时。每次扩容是2倍。
-
语法:List arrayList = new ArrayList();
会一次给10个元素的内存,超过10个后会扩容;
#queue
public static void main(String[] args) {
Queue queue1 = new LinkedList();
for (int i = 1;i<6;i++){
boolean offer1 = queue1.offer(i*11);
}
System.out.println("Queen集合元素为:"+queue1);
//打印队列首位元素peek
System.out.println("首位元素为:"+queue1.peek());
//出队元素poll,循环出队
for(int i=0;i<= queue1.size();i++){
Object poll1 = queue1.poll();
System.out.println("出队元素为:"+poll1);
}
System.out.println("Queen集合元素为:"+queue1);
}
}
18-泛型
object是所有类型父类
集合取出元素,也是object类型,要是用元素真实的类型,就要强转
概念
- 集合名称的右侧使用<数据类型>
- 明确集合中可以存放的元素类型
- 若放入其它类型的元素则编译报错
- 泛型只在编译时期有效,在运行时期不区分是什么类型。
- <>等号前面不可省略,等号后面的可以省略:List list2 = new ArrayList<>();
自定义泛型
可以声明一个类,然后在类名后<>里自定义类型<E,T…>,后面会沿用这个类型
父子类泛型
父类有泛型,子类可以保留泛型也可以指定泛型类型
- 子类不保留泛型T且没有指定类型(丢弃泛型)
public class SubAnmial extends Anmial{}
- 子类不保留泛型,但指定了父类的泛型T
public class SubAnmial extends Anmial<String>{}
- 子类保留父类泛型T
public class SubAnmial<T> extends Anmial<T>{
}
- 子类增加自己的泛型
public class SubAnmial<T,E> extends Anmial<T>{
}
- 泛型中有三种通配符形式
-
<?>
- 无限制通配符
- 可以传入任意类型的参数
-
<? extends E>
- 类型的上界是 E
- 只能是 E 或者是 E 的子类
-
<? super E>
- 类型的下界是 E
- 只能是 E 或者是 E 的父类
-
set集合
二叉树
有序二叉树:
tractset
collect集合是单个集合,Map集合数据是成对出现
Map集合<K,V>
- k不能重复,一个k只能有一个v;
io流:字节流、字符流
写入本地文件:.FileWriter()
读取本地文件:.FileReader(),读取一个,光标往后移动一个
package iop;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReadDemo {
public static void main(String[] args) throws FileNotFoundException {
FileReader fileReader = null;
try {
//1. 创建对象;
fileReader = new FileReader("/Users/a1/Desktop/iotest/io.txt");
/*
//2. 读取文本中第一个数据;
int read = fileReader.read();
System.out.println("读出来的内容:"+read);
//读取所有数据
int res = 0;
while (-1 != (res = fileReader.read())){
System.out.println("全部内容:"+(char)res);
}
*/
//读取部分内容
char[] chars1 = new char[5];
int read2 = fileReader.read(chars1,1,3);
System.out.println("取到的个数:"+read2);
System.out.println(chars1);
for(char c:chars1){
System.out.println(c);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(null != fileReader){
//3.关闭流;
fileReader.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
字节流:可以读写所有类型的文件
大文件用BufferInputStream BufferOutStream
stream流
不是任何一种类型,是一种保存数据结构