Java学习17 2020-02-22

内容

1.List
2.哈希表原理图
3.HashSet
4.SortedSet

在正式讲解之前,还是把上一篇的一个图拿过来。这个图十分重要

继承结构图

一.List

1.List介绍

(1)List是接口,继承Collection
(2)List集合存储元素的特点
有序(List集合中存储有下标,类似于数组)
存进去是什么顺序,取出来还是按照这个顺序取出
可重复

2.List使用
import java.util.*;



public class 测试程序 {                                                                                                             
                                                                                                                                
                                                                                                                                
    public static void main(String[] args)  {                                                                                   
    
        //1.创建List集合(List集合是接口,继承Collection)
        List a = new ArrayList();//括号里填初始化容量,不填默认是10
        
        //2.添加元素
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(4);
        a.add(4);
        
        //遍历
        Iterator b = a.iterator();
        while(b.hasNext()) {
            System.out.println(b.next());
        }
        
    }                                                                                                                           
}
3.深入List集合

①ArrayList集合和Vector集合底层是数组,数组是有下标的,所以它有很多类似数组的特性
②ArrayList集合底层默认初始化容量是 10 ,扩大之后的容量是原容量的1.5倍
③Vector集合底层默认初始化容量也是10,扩大之后的容量是原容量的2倍
④如何优化?
尽量减少扩容操作,因为扩容需要数组拷贝,数组拷贝很耗内存。一般推荐在创建集合的时候指定初始化容量

4.使用示例
import java.util.*;



public class 测试程序 {                                                                                                             
                 
    //深入List
                                                                                                                                
    public static void main(String[] args)  {                                                                                   
    
        //1.创建List集合(List集合是抽象类,继承CollectionayList();
        List a = new ArrayList();
        
        //2.添加元素
        a.add(1);
        a.add(2);
        a.add(3);
        
        //2.在下标为1的位置上添加6
        a.add(1,6);
        
        //3.取得元素
        System.out.println(a.get(0));//输出1
        System.out.println(a.get(1));//输出6
        
        //遍历(List集合特有的遍历方式)
        for(int i = 0;i < a.size();i++) {
            Object element = a.get(i);
            
            System.out.println(element);
        }
    }                                                                                                                           
}

二.哈希表原理图

哈希表原理图

三.HashSet

1.特点及注意事项

1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构(原理图在上面)
2.hashSet其实是HashMap中的key部分,HashSet有什么特点,HashMap中的key应该具有相同的特点
3.HashMap和HashSet初始化容量都是 16 ,默认加载因子是0.75

2.哈希表

①哈希表又叫做散列表哈希表底层是一个数组,这个数组中每一个元素是一个单向链表
②每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相等的
③hash值实际上是key调用hashCode方法,再通过“hash function”转换成的值

3.如何向哈希表中添加元素

①先调用被储存的key的hashCode方法,经过某个算法得出hash值
②如果在这个哈希表中不存在这个hash值,则直接加入元素,如果该hash值已经存在,继续调用key之间的equals方法
③如果equals方法返回false,则将该元素添加,如果equals方法返回true,则放弃添加该元素

4.使用示例
import java.util.*;



public class 测试程序 {                                                                                                             
                 
    
                                                                                                                                
    public static void main(String[] args)  {                                                                                   
    
        //1.创建Set集合
        Set s = new HashSet();
        
        //2.添加元素,验证它是无序不可重复的
        //Set集合通常不能记住元素的添加顺序
        s.add(1);
        s.add(1);//这个就加不上去了
        s.add(100);
        s.add(86);
        s.add(110);
        
        //遍历
        Iterator it = s.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        
        
    }                                                                                                                           
}

注意:Set集合通常不能记住元素的添加顺序,并不是说一定不按顺序。但是它不允许有相同元素再添加这个是一定的。

5.关于往Set集合中存储的元素,该元素的hashCode和equals方法

注意

存储在HashSet集合或者HashMap集合key部分的元素,需要同时重写 hashCode和equals方法

使用示例

import java.util.*;



public class 测试程序 {                                                                                                             
 /*
  * 关于往Set集合中存储的元素,该元素的hashCode和equals方法
  * HashMap中有一个put方法,put(key,value) key是无序不可重复的
   结论:
   存储在HashSet集合或者HashMap集合key部分的元素,需要同时重写 hashCode和equals方法
  */
    
                                                                                                                                
    public static void main(String[] args)  {                                                                                   
    
        //1.创建Set集合
        Set s = new HashSet();
        
        //2.创建员工对象
        Employee e1 = new Employee("1000","Jack");
        Employee e2 = new Employee("1000","Jack");
        Employee e3 = new Employee("2000","SCOTT");
        Employee e4 = new Employee("2001","SMITCH");
        Employee e5 = new Employee("3000","JIM");
        Employee e6 = new Employee("3001","JOHN");
        
        System.out.println(e1.hashCode());
        System.out.println(e2.hashCode());
        /*
         * 输出
         * 1507423
           1507423
           两者相同,同时也验证了String中hasCode()方法的特点:只要字符串一样,就返回相同的值
           验证了结论
         */
        //3.添加元素
        s.add(e1);
        s.add(e2);
        s.add(e3);
        s.add(e4);
        s.add(e5);
        s.add(e6);
        
        //4.查看集合中元素的个数
        System.out.println(s.size());
        /*
         * 在没有重写Employee中的hasCode和equals方法的时候,这里输出6
         * 但是按照现实的业务逻辑,e1和e2是同一个人,e2不应该再加进去
         * 但是因为e1和e2都是new出来的。它们经过hasCode方法之后得到的值是不一样的,所以就加进去了
         * 所以这里为了避免这样的问题,应该重写hasCode和equals方法
         */
        //重写了之后,就输出5
   
        
    }                                                                                                                           
}     

//创建员工类
class Employee{
    
    String num;
    String name;
    
    Employee(String num,String name){
        this.num = num;
        this.name = name;
    }
    
    //重写hasCode方法
    public int hashCode() {
        //直接以员工编号分组
        //String已经重写了hasCode方法,直接返回String的就可以
        return num.hashCode();//如果两个编号相同,则返回相同的值
    }
    
    //重写equals方法
    public boolean equals(Object o) {
        if(this == o)  return true;
        
        if(o instanceof Employee) {
            Employee temp = (Employee)o;
            if(temp.num.equals(this.num) && temp.name.equals(this.name)) {
                return true;
            }
        }
        
        return false;
    }
}

先去重写hashCode方法,再去重写equals方法,前者第一,后者第二。前者执行完,再执行后者

四.SortedSet

1.介绍

①SortedSet继承Set,也是一个接口,实现类是TreeSet
②SortedSet存储的数据无序不可重复,但是存进去的元素可以按照元素大小顺序自动排列

2.使用示例(验证特点)
package 对象;

import java.util.*;
import java.text.*;


public class 测试程序 {                                                                                                             

    
                                                                                                                                
    public static void main(String[] args) throws ParseException  {                                                                                   
    
        //1.创建集合
        SortedSet ss = new TreeSet();
        
        //2.添加整型元素
        ss.add(10);
        ss.add(20);
        ss.add(40);
        ss.add(30);
        ss.add(25);
        ss.add(13);
        
        //3.遍历,验证
        Iterator it = ss.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        /*输出:
         *  10
            13
            20
            25
            30
            40

         */
        
        //1.创建集合
        SortedSet strs = new TreeSet();
        
        //2.添加字符串数据
        strs.add("JACK");
        strs.add("SUN");
        strs.add("KOOK");
        strs.add("LUCY");
        strs.add("KING");
        
        //3.遍历,验证
        it = strs.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        /*
         * 输出
         *  JACK
            KING
            KOOK
            LUCY
            SUN
是从a~z开始比较,第一个字母相同就比第二个字母。
所以再一次得到验证,字符串也可以
         */
        
        //1.创建集合
        SortedSet times = new TreeSet();
        
        //2.创建日期
        String st1 = "2019-01-01";
        String st2 = "2020-01-01";
        String st3 = "2019-08-01";
        String st4 = "2017-01-01";
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        
        Date t1 = sdf.parse(st1);
        Date t2 = sdf.parse(st2);
        Date t3 = sdf.parse(st3);
        Date t4 = sdf.parse(st4);
        
        //3.添加元素
        times.add(t1);
        times.add(t2);
        times.add(t3);
        times.add(t4);
  
        //3.遍历,验证
        it = times.iterator();
        while(it.hasNext()) {
            Object element = it.next();
            
            if(element instanceof Date) {
                Date d = (Date)element;
                System.out.println(sdf.format(d));
            }
            
        }
        /*
         * 输出:
         *  2017-01-01
            2019-01-01
            2019-08-01
            2020-01-01

         */
    }                                                                                                                           
}
3.为何SortedSet集合存储元素可以自动排序?

因为被存储的元素实现了Comparable接口,SUN编写TreeSet集合在添加元素的时候,会调用compareTo方法完成比较,然后实现排序

4.示例:自己定义的类实现排序
package 对象;

import java.util.*;



public class 测试程序 {                                                                                                             

    
                                                                                                                                
    public static void main(String[] args) {
    
        //1.创建集合
        SortedSet users = new TreeSet();
        
        //2.创建对象
        User u1 = new User(15);
        User u2 = new User(16);
        User u3 = new User(12);
        User u4 = new User(11);
        User u5 = new User(17);
        
        //3.添加元素
        users.add(u1);
        users.add(u2);
        users.add(u3);
        users.add(u4);
        users.add(u5);
        
        //4.遍历
        Iterator it = users.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        /*
         * 输出
         *  User[age=11]
            User[age=12]
            User[age=15]
            User[age=16]
            User[age=17]

        有升序也有倒序,主要是return那个地方age1和age2互换位置即可
         */
    }                                                                                                                           
}     

class User implements Comparable{//要想让自己单独定义的类可以比较,必须实现 Comparable接口
    int age;
    
    User(int age){
        this.age = age;
    }
    
    //重写toString方法
    public String toString(){
        return "User[age="+age+"]";
    }
    
    //实现java.lang.Comparable接口中的comparaTo方法
    //该方法程序员负责是实现,SUN提供的程序已经调用了该方法
    public int compareTo(Object o) {
        //编写一个比较规则
        int age1 = this.age;
        int age2 = ((User)o).age;
        return age1 - age2;
    }


}
5.SortedSet集合排序的另外一种方式

让SortedSet集合排序还有一个方式
单独编写一个比较器
具体做法是写一个类实现Comparator,因为Comparator是一个接口

6.使用示例
package 对象;

import java.util.*;



public class 测试程序 {                                                                                                             

    
                                                                                                                                
    public static void main(String[] args) {
    
        //1.创建集合
        SortedSet products = new TreeSet(new ProductComparator());

        //2.创建对象
        Product p1 = new Product(1.0);
        Product p2 = new Product(2.0);
        Product p3 = new Product(1.1);
        Product p4 = new Product(2.6);
        
        //3.添加元素
        products.add(p1);
        products.add(p2);
        products.add(p3);
        products.add(p4);
        
        //4.遍历
        Iterator it = products.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        /*
         * 输出
         *  1.0
            1.1
            2.0
            2.6

         */
        

    }
}

//创建商品类
class Product{
    double price;
    
    Product(double price){
        this.price = price;
    }
    
    //重写toString方法
    public String toString() {
        return price + "";
    }
}

//单独编写一个比较器
class ProductComparator implements Comparator{
    
    //需求:按照商品价格排序
    public int compare(Object o1,Object o2) {
        
        double price1 = ((Product)o1).price;
        double price2 = ((Product)o2).price;
        
        if(price1 == price2) {
            return 0;
        }else if(price1 > price2) {
            return 1;
        }else {
            return -1;
        }
    }
}

推荐使用第二种方式,因为可以降低程序的耦合度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值