day07 集合

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();

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值