2024年4月7号java学习
权限修饰符
代码块
局部代码块
提前结束变量的生命周期
构造代码块
抽取构造代码块中重复的内容,先执行构造代码块再执行构造方法
静态代码块
数据初始化,随着类的加载而加载并且只执行一次
示例代码
集合
集合分为单列集合(Collection)和多列集合(Map)
equals方法
如果没有在类中重写equals方法,那么调用的就是Object类中的equals的方法,那么比较的就是地址值
示例代码
package List.equals;
import java.util.ArrayList;
public class equalsDemo {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Student s1 = new Student("li", 18);
Student s2 = new Student("lwj", 18);
Student s3 = new Student("wa", 18);
Student s4 = new Student("li", 18);
list.add(s1);
list.add(s2);
list.add(s3);
//如果没有重写Student中的equals方法那么使用的Object的equals方法,那么比较的是地址值,所以是false
System.out.println(list.contains(s4));
}
}
重写之后
package List.equals;
import java.util.ArrayList;
public class equalsDemo {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Student s1 = new Student("li", 18);
Student s2 = new Student("lwj", 18);
Student s3 = new Student("wa", 18);
Student s4 = new Student("li", 18);
list.add(s1);
list.add(s2);
list.add(s3);
//重写Student中的equals方法,那么就会是true了,因为比较的是当名字和年龄
System.out.println(list.contains(s4));
}
}
迭代器
迭代器使用来遍历集合的
迭代器的三个方法
hasNext()用来判断当前位置有没有元素,有元素返回true,没有返回false
next()用来获取当前的元素,并让指针往后面走
示例代码
package iterator;
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("123");
list.add("456");
list.add("789");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String ans = iterator.next();
System.out.println(ans);
}
}
}
增强for循环
package iterator;
import java.util.ArrayList;
import java.util.Iterator;
public class ForPlus {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("123");
list.add("456");
list.add("789");
Iterator<String> iterator = list.iterator();
//快速生成:集合名.for
for (String s : list) {
//不能改变集合中原本的元素
System.out.println(s);
list.remove(s);
}
System.out.println(list);
}
}
泛型
泛型中只能是引用数据类型
如果没有指定数据类型那么就是默认的Object类型
泛型的好处:
统一数据类型
把运行期间的问题提前到了编译期间,避免了强制类型转换出现的异常,因为类型在编译期间就已经确定下来了
泛型类
当不确定类中变量的数据类型时就可以使用泛型类
泛型方法
当不确定方法中形参类型时,可以把方法定义成一个泛型方法
泛型的继承和通配符
泛型不具备继承性,但数据具有继承性
示例代码
package Generics;
import java.lang.reflect.Array;
import java.time.ZoneId;
import java.util.ArrayList;
public class jichengDemo {
public static void main(String[] args) {
ArrayList<Ye> list1 = new ArrayList<>();
ArrayList<Fu> list2 = new ArrayList<>();
//数据具备继承性
list1.add(new Ye());
list1.add(new Fu());
list1.add(new Zi());
//是什么类型就只能够传递什么类型,不能够继承传递
f(list1);
f(list2);
}
public static void f(ArrayList<Ye> list) {
}
}
class Ye{}
class Fu extends Ye {}
class Zi extends Ye {}
统配符
?表示可以是任何类型,但可以使用extends和super来修饰,这样可以实现限定类型
? extends E表示只有E和它的子类可以传递
? super E表示只有E和它的父类可以传递
Set集合
特点:添加的元素是无序的、无重复的、无索引的
Set集合的实现类
HashSet:无序、无重复、无索引
LinkedHashSet:有序、无重复、无索引
TreeSet:可排序、无重复、无索引
HashSet的底层原理
底层使用哈希表来存储数据
哈希表的组成:
JDK8以前:数组+链表
JDK8以后:数组+链表+红黑树
自定义数据类型要重写hashcode函数,因为不写调用的时Object的equals和hashCode方法,那么计算就是地址值
示例代码
package set;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<Student> s = new HashSet<>();
s.add(new Student("li", 18));
s.add(new Student("li", 18));
System.out.println(s.size());//因为使用的是Obeject的方法,那么使用的是地址值来判断是不是相同的,使用我们需要重写hashcode方法
}
}
重写之后的
package set;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<Student> s = new HashSet<>();
s.add(new Student("li", 18));
s.add(new Student("li", 18));
System.out.println(s.size());//重写之后比较的其中的属性值,那么它们的属性值相同使用hash值也一样,又因为不能又重复的元素,所以size变成1
}
}
LinkedHashSet的底层原理
有序:指的是保证存入和取出的顺序一致
原理:底层仍然是哈希表但使用一个双向链表来保证有序(排序算法的稳定性),链表的特性