Code
HashCodeTest对象的哈希值
public class Student {
//重写父类的方法hashCode,等于说哈希值可以改变,从1846274136改成9527,类似于自己弄的编号,
// 和以前讲的地址值(java我们不知道,只是那样说而已,Java中我们说的是哈希值)不一样,以前的地址值类似于身份证,是不能改变的,和哈希值不一样
public int hashCode(){
return 9527;
}
}
/*
* 对象的哈希值:自动给你算哈希值
*
* Object类,所有类的父类
* 定义方法
* public native int hashCode()
*
* 每个类都具有这个方法
*
* 调用方法 hashCode()结果 十进制的整数
* 调用方法 toString()结果 十六进制整数
*
* 结论: Student@1b6d3586 不要称为地址值
* 称为对象的哈希值
* 对象的哈希值和地址,无关,没有任何关系
*
* 哈希值: 理解为仅仅是一个 十进制的整数而已
*/
public class HashCodeTest对象的哈希值 {
public static void main(String[] args) {
Student student = new Student();
//调用Student对象的方法 hashCode()
int i = student.hashCode();//1846274136
System.out.println(i);
//调用Student对象的方法 toString()
System.out.println(student.toString());//com.itheima.Code.Student@6e0be858(十六进制)=1846274136(十进制)
}
}
StringHashCodeTest字符串对象
/*
* java.lang.String 最常用类,字符串对象
*
* String类继承父类Object,重写了父类的方法 hashCode()
*
*/
public class StringHashCodeTest字符串对象 {
public static void main(String[] args) {
//创建2个字符串对象
String s1 = new String("abc");
String s2 = new String("abc");
//对象的比较运算
System.out.println(s1==s2);//false
//调用s1和s2对象的方法hashCode
System.out.println(s1.hashCode());//96354
System.out.println(s2.hashCode());//96354
//如果2个字符串内容不一样,是否有可能计算出相同的哈希值呢
String s3 = "重地";
String s4 = "通话";
System.out.println(s3.hashCode());
System.out.println(s4.hashCode());
System.out.println(s3.equals(s4)); // false
}
}
---------------------------------------------------------------
Collections比较器工具类
import java.util.Objects;
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
//以下是哈希表判重的
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/*
* java.util.Collections 类 集合操作的工具类,不是Collection,两个不一样
* 就像数组的工具类Arrays
*
* Collections类的方法全部静态修饰,类名直接调用(如果不是静态,需要new,用变量名.调用)
* 常用方法:
* static void shuffle(List list) 对集合中的元素随机排列
* static void sort(List list)对集合中的 元素升序排列
* static int binarySearch(List list,Object o)对集合进行二分搜索
*/
public class CollectionsTest {
public static void main(String[] args) {
m02();
}
/*
* 集合,进行升序排列
*
*****集合存储自定义对象,这里引入Person和比较器Comparator*********
*
* 自定义的对象Person,无法直接排序,没有顺序
* Collections.sort(List集合, 比较器对象)
* 方法sort根据比较器的结果进行排序
* 比较器对象 Comparator接口
* 接口方法: int compare()
*/
public static void m02(){
//创建集合,存储自定义Person对象
List<Person>list=new ArrayList<>();
list.add(new Person("a",11));
//list.add(new Person("c",13));
list.add(new Person("b",12));
//第一种,运用Collections.sort(List集合, 比较器对象)进行对象比较
//Collections工具类的静态方法sort,排序
//传递比较器对象, sort方法调用接口实现类的重写方法compare
//传递集合中的元素
Collections.sort(list,new MyComparator());
System.out.println(list);
//第二种比较方法,运用匿名内部类
//new Comparator<Person>=new MyComparator()
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
System.out.println(o1);//Person{name='a', age=11}
return o1.getAge()-o2.getAge();
}
});
System.out.println(list);
}
/*
* 集合,进行升序排列
*/
public static void m01(){
List<String>list=new ArrayList<>();
list.add("i");
list.add("love");
list.add("java");
list.add("money");
System.out.println(list);
//Collections工具类的静态方法sort,排序
Collections.sort(list);
//会根据首写字母的顺序排
System.out.println(list);
}
}
import java.util.Comparator;
/*
*比较器Comparator接口
* 自定义的比较器:
* 实现接口 java.util.Comparator
* 重写接口中的抽象方法
*
*
* 定义比较器的目的:是为了比较Person对象
* 接口Comparator<T> :T就是你要比较的对象的类型
* */
public class MyComparator implements Comparator<Person>{
// int compare(T o1, T o2)
/*
* 方法的返回值:int类型
* 返回值正数,负数 0
* 大 小 0
*
* p1后来的对象,p2先来的对象
*
* p1后来的和p2先来的比: 结果是负数,后来的小,排前面
* p1后来的和p2先来的比: 结果是正数,后来的大,排后面
*/
@Override
public int compare(Person o1, Person o2) {
//进行Person对象的比较
//两个Person对象的年龄差
return o1.getAge()-o2.getAge();
}
}
---------------------------------------------------------------
Set集合
HashSet
import java.util.Objects;
public class Person {
private String name;
private int age;
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
import java.util.HashSet;
import java.util.Set;
/*
* java.util.HashSet类, 实现接口Set
*
* HashSet集合自身特点:
* 1:HashSet集合,自己没有功能,依赖另一个集合HahMap
*
* 2:集合底层是数据结构哈希表
*
* 3:无序集合
* 元素的存储顺序和去除顺序,不一定一致
*
* 4:集合是线程不安全的集合,运行速度快
* */
public class HashSetTest {
public static void main(String[] args) {
m02();
}
/*
* 集合HashSet存储自定义对象Person
* 1 : 本例中,Person对象重复吗
* 2: 多个Person对象中,如果姓名和年龄相同
* 看成是一个对象,不想存储
* Person类,重写方法hashCode()和equals()
*/
public static void m02(){
Set<Person>set=new HashSet<>();
set.add(new Person("a",101));
set.add(new Person("b",102));
set.add(new Person("c",103));
set.add(new Person("c",103));
set.add(new Person("e",104));
for (Person p : set) {
System.out.println(p);
}
}
/*
* 集合HashSet存储字符串
*
* 这里介绍一下筛选方法
* 依据的是对象自己的方法:hashCode()和equals()
* 两个对象hashCode()不同:不是同一个对象
* 两个对象hashCode()相同,再比较equals,返回true:同一个对象
* 两个对象hashCode()相同,再比较equals,返回false:不是同一个对象
* */
public static void m01(){
Set<String>set=new HashSet<>();
set.add("abc");
set.add(new String("abc"));
set.add("重地");
set.add("通话");
System.out.println(set);
/*
* 哈希值"abc"和new String("abc")相同
* 比较equals,又相同,所以输出一个就行(Set是不能重复的)
*
* 哈希值"重地"和"通话"相同
* 但是equals的内容不同,所以都输出
* */
}
}
LinkedHashSet
import java.util.LinkedHashSet;
import java.util.Set;
/*
* java.util.LinkedHashSet类,继承HashSet
* HashSet集合,底层是哈希表结构,数组+链表(单项链表)
* 无序集合
* LinkedHashSet集合,底层是哈希表结构,数组+链表(双向结构)
* 集合,是有序的Set集合
* */
public class LinkedHashSetTest {
public static void main(String[] args) {
Set<String>set=new LinkedHashSet<>();
set.add("b");
set.add("a");
set.add("c");
System.out.println(set);
}
}
Set
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*Set类似于List地位
* java.util.Set 接口 继承Collection接口
* Set集 特点:
* Set集合不允许重复元素
* Set集合没有索引
* 输出无序
*
*
* Set接口实现类:
* HashSet,LinkedHashSet 具备以上的特点
* 用法参照List及其实现类ArrarList和LinkedList
*
* Set接口中的抽象方法,和父类接口Collection一样
* */
public class SetTest {
public static void main(String[] args) {
//创建Set集合,存储字符串,遍历
Set<String>set=new HashSet<>();
set.add("i");
set.add("love");
set.add("you");
set.add("i");
//遍历Set集合,遍历 迭代器或者增强for
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
System.out.println(next);
}
System.out.println("***********************");
//输出的顺序随机,不比List输出的有顺序
for (String s : set) {
System.out.println(s);
}
}
}
/*
增强格式:
for(数据类型 变量名 : 集合或者数组名){
}
*/
---------------------------------------------------------------
增强for
/*
* JDK5新特性: 增强型的for循环
* java.lang.Iterable凡是此接口的实现类:都可以使用增强型for循环,包含数组
* 所有的Collection接口下的集合都可以使用,所有单列集合都行
*
* 推荐尽量使用增强for循环,减少代码书写
* 语法:
* 增强形式
* for(数据类型 变量名 : 集合或者数组名){
*
* }
* 数据类型: 指的是集合或者数组存储元素的类型
*
* 传统形式
* for(初始化变量 i = 0 ; 条件 ; 增量++){
*
* }
*
* 增强形式for:
* 优势: 代码量小了
* 弊端: 遍历可以,操作容器中的元素不行
*
* 比喻: 只能看,不能摸
*
* 增强for不存在: 编译特效
* javac: 编译java文件时候,自动将增强for编译为迭代器
* 遍历数组,将增强for编译为传统for
*/
import com.itheima.Collections比较器工具类.Person;
import java.util.ArrayList;
import java.util.List;
public class ForEachTest {
public static void main(String[] args) {
m01();
}
//增强形式,集合遍历
public static void m02(){
List<Person>list=new ArrayList<>();
list.add(new Person("a",10));
list.add(new Person("b",10));
list.add(new Person("c",10));
list.add(new Person("d",10));
for (Person p : list) {
//输出对象p,输出该对象toString()
System.out.println(p);
}
}
// 增强形式 数组遍历
// for(数据类型 变量名 : 集合或者数组名){
//
// }
// 不打乱输入的顺序
public static void m01(){
int[]arr={1,3,4,5};
for (int i : arr) {
//以下进行了输出结果+1的运算
System.out.print(i+1);
}
//没有改变原数组
System.out.println(arr[0]);
for (int i : arr) {
System.out.println(i);
}
}
}
---------------------------------------------------------------
泛型
01
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
* 泛型“:Jdk5出现的新特性
* 是一个保证程序的安全机制
*
* 泛型:如何保证程序安全性---那就是强制集合存储指定的类型
* 容器中数据类型的检测,类型不匹配,编译失败
* 不可能运行
* 安全问题,运行的时间,要提前到编译时间,以确保安全
*
* 泛型好处:
* 1:安全
* 2:减少代码量
* 3:避免了数据类型的强制转换
*
* 假泛型:编译后的class文件只没有泛型
* 源码是存在的,javac自动检测类型,类型如果一致(比如都是Person类型),编译成功,否则编译失败
* */
public class Generic01 {
public static void main(String[] args) {
m02();
}
/*
* 带有泛型的集合
*/
public static void m02(){
//集合带有泛型<>
List<String>list=new ArrayList<>();
list.add("java");
list.add("heima");
list.add("web");
//list.add(1);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
//集合明确存储String,取出的元素也是字符串
String next = iterator.next();
System.out.println(next.length());
}
}
/*
* 没有泛型的时候
* 集合可以存储什么数据类型,任意
* 出现类型的转换问题: 出现的时机是运行
*/
public static void m01(){
List list=new ArrayList();
list.add("java");
list.add("heima");
list.add("web");
list.add(1);//这是int型的,会报错
//迭代器遍历集合
Iterator iterator = list.iterator();
while (iterator.hasNext()){
//取出元素,只能是Object
// Object next = iterator.next();
//Object转成String
String next =(String) iterator.next();
System.out.println(next.length());
}
}
}
02
import java.util.ArrayList;
import java.util.List;
/*
* ArrayList<E> E:Element元素
* LinkedList<E>
* Comparator<T> T:Type 类型
* Map<K,V> K:key V:value
*
* 无论E或者T,只是一个变量名字而已
*
* List<String>list=new ArrayList<String>();
* E:变成String 等待指定数据类型
* add(E e); add(String e)
* E get(int index) : String get(索引)
* */
public class Generic02 {
public static void main(String[] args) {
List<String>list=new ArrayList<>();
list.add("a");
list.get(1);
}
}
03自定义泛型
/*
* 自定义的泛型类
* <QQ>定义变量名
*
* QQ:创建对象的时候,被指定 类型
* */
public class Factory <QQ> {
private QQ name;
public QQ getName() {
return name;
}
public void setName(QQ name) {
this.name = name;
}
}
/*
* 自定义泛型:
* 自己定义的<>
* */
public class GenericTest {
public static void main(String[] args) {
//创建的工厂类对象,指定泛型
Factory<Integer> factory = new Factory<>();
factory.setName(100);
System.out.println(factory.getName());
Factory<String> factory1 = new Factory<>();
factory1.setName("haha");
System.out.println(factory1.getName());
}
}
04带有泛型的方法
public class Factory <QQ>{
private QQ name;
/*111
* 方法可以被定义为静态方法
* 类型上的泛型<QQ>需要创建对象,指定数据类型
* 可是静态方法,无需对象,直接类名调用
*
* 静态方法,泛型不能和类上一样TT和QQ不能一样
* */
public static <TT>void function(TT q){
//输出q,q是传入的对象
System.out.println(q);
}
/*222
* 定义方法,方法上拥有自己的泛型
* 在方法的声明上,定义泛型
* 写在返回值类型的前面
*
* 调用此方法:TT和QQ 不是一回事
* 调用者传递什么类型,就是什么类型
* */
public <TT>void show(TT t){
//输出t,t是传入的对象
System.out.println(t);
}
public QQ getName() {
return name;
}
public void setName(QQ name) {
this.name = name;
}
}
/*
* 自定义带有泛型的方法
* */
public class GenericTest {
public static void main(String[] args) {
Factory<String> factory = new Factory<>();
//222不是静态的,对象调用
factory.show(5.2);
factory.show(true);
//111静态的,直接类名调用
Factory.function("aa");
Factory.function(123);
}
}
05带有泛型的接口
/*
* 带有泛型的接口
* */
public interface MyInterface <E>{
public abstract void inter(E e);
}
/*
* 定义类,实现接口
* 这个类是不理会泛型的
* */
public class MyInterfaceImpl01<E> implements MyInterface<E>{
//这里的E可以是任意数据类型,E也可以写成T或者String
@Override
public void inter(E e) {
//输出e,e是传入的对象
System.out.println(e);
}
}
/*
* 实现类,实现接口,同时指定数据类型(有局限性)
* 指定了<>里面的类型,只能是此类型,别的会报错
* */
public class MyInterfaceImpl02 implements MyInterface<String>{
@Override
public void inter(String s) {
System.out.println(s);
}
}
/*
* 自定义的泛型接口
* */
public class GenericTest {
public static void main(String[] args) {
//多态创建对象,针对MyInterfaceImpl01,泛型的接口
MyInterface<String>my01=new MyInterfaceImpl01<>();
my01.inter("aaa");
MyInterface<Integer>my02=new MyInterfaceImpl01<>();
my02.inter(111);
//多态创建对象,针对MyInterfaceImpl02的指定类型String
//下面的String只能是String,不能改成别的
MyInterface<String>my03=new MyInterfaceImpl02();
my03.inter("bbb");
}
}
06通配符
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
* 泛型的通配符 ?
* 通通匹配的字符
* */
public class GenericTest {
public static void main(String[] args) {
//创建2个集合,一个存储String,一个存储Integer
List<Integer>integerList=new ArrayList<>();
integerList.add(1);
integerList.add(2);
List<String>stringList=new ArrayList<>();
stringList.add("abc");
stringList.add("bcd");
//调用方法
iterator(integerList);
iterator(stringList);
}
/*
* 定义方法:一个方法可以同时迭代2个集合
* 集合的泛型不明确,只能使用通配符 ?(任意类型)
* */
public static void iterator(List<?>list){
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
//取出元素 迭代器方法next() 返回值类型 ?
Object next = iterator.next();
System.out.println(next);
}
}
}
07通配符的成员含有子类
public abstract class Employee {
private String name;
private int age;
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 Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee() {
}
public abstract void work();
}
public class Manager extends Employee {
@Override
public void work() {
System.out.println("管理班级"+super.getName()+"..."+super.getAge());
}
}
public class Teacher extends Employee {
@Override
public void work() {
System.out.println("老师上课"+super.getName()+"..."+super.getAge());
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
* 抽象类: 员工案例
* 老师,班主任,继承员工
*/
public class GenericTest {
public static void main(String[] args) {
//创建集合,存储老师对象
List<Teacher>teacherList=new ArrayList<>();
//创建集合,存储班主任对象
List<Manager>managerList=new ArrayList<>();
Teacher t1 = new Teacher();
t1.setName("老师名字1");
t1.setAge(11);
Teacher t2 = new Teacher();
t2.setName("老师名字2");
t2.setAge(22);
Manager m1 = new Manager();
m1.setName("班主任名字1");
m1.setAge(100);
Manager m2 = new Manager();
m2.setName("班主任名字2");
m2.setAge(200);
//加进集合中
teacherList.add(t1);
teacherList.add(t2);
managerList.add(m1);
managerList.add(m2);
//调用方法
iterator(teacherList);
iterator(managerList);
}
/*
* 定义方法,同时遍历2个集合
* 遍历的同时,调用方法work()
* 利用泛型实现安全的程序
* 泛型使用通配符? 可以接收任意的类型
* 一旦强制转换,出现异常
*
* 必须:
* 泛型只能是Employee类型或者是他的子类
* 一个确定 :Employee
* 一个不确定 :子类
*
*
* 泛型的限定
* ? extends Employee 传递集合,集合的泛型只能是Employee或者是他的子类
* 泛型的上限
*
* ? super Employee 传递集合,集合的泛型只能是 Employee或者是他的父类
* 泛型的下限
* */
public static void iterator(List<? extends Employee>list){
Iterator<? extends Employee> iterator = list.iterator();
while (iterator.hasNext()){
//取出的元素类型是Object,不能调用方法work()
//但是转成Teacher不安全,转成Manager不安全
//所以用他们的父类Employee
Employee next = iterator.next();
next.work();
}
}
}