2019-05-27 Java学习日记 day17

Hashset集合

存储字符串并遍历

import java.util.HashSet;

public class dmo1_hashset {
        //set集合,无索引,不可以重复,无序(存取不一致)
    public static void main(String[] args) {
        HashSet<String> hSet=new HashSet<>();  //创建hashset对象
        boolean b1=hSet.add("a");
        boolean b2=hSet.add("a");    //当向set集合中存储重复元素的时候返回为false
        hSet.add("b");
        hSet.add("c");
        hSet.add("d");
        
        System.out.println(hSet);  //hashset的继承体系中有重写toString方法
        //System.out.println(b1);
        //System.out.println(b2);
        for (String string : hSet) {  //只要能用迭代器迭代的,就可以使用增强for循环遍历
            System.out.println(string);
        }

    }

}
案例

 

存储自定义对象保证元素唯一性

Hashset原理

  我们使用set集合都是需要去掉重复元素的,如果在存储的时候逐个equals()比较,效率较低,哈希算法提高了重复的效率,降低了使用equals()方法的次数

  当Hashset调用add()方法存储对象的时候,先调用对象的hashset()方法得到一个哈希值,然后在集合中查找是否有哈希值相同的对象:

  如果没有哈希值相同的对象就直接存入集合

  如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入,true则不存

 

将自定义累的对象存入Hashset去重复

  类中必须重写hashCode()和equals()方法

  hashCode():属性相同的对象返回值此项相同,属性不同的返回值尽量不同(提高效率)

  equals():属性相同返回true,属性不同返回false,返回false的时候存储 

 

import java.util.HashSet;

import tan.jung.bean.Person;

public class demo2_hashset {

    public static void main(String[] args) {
        HashSet<Person> hs =new HashSet<>();
        hs.add(new Person("张三",23));
        hs.add(new Person("张三",23));
        hs.add(new Person("张三",23));
        hs.add(new Person("李四",24));
        hs.add(new Person("李四",24));
        
        System.out.println(hs);  //需要重写equals和HashCode方法
        

    }

}

//第二个包
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) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    /*@Override
    public boolean equals(Object obj) {
        System.out.println("执行了");
        Person p=(Person)obj;
        return this.name.equals(p.name) && this.age == p.age;  
    }
    @Override
    public int hashCode() {
        final  int num=38;
        return name.hashCode() * num +age;
    }*/
    @Override
    public int hashCode() {
        final int prime = 31; //31是一个质数,质数是能被1和自己本身整除的数 ,即不大也不小,比较好算,2的五次方-1,2向左移动五位
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)                 //调用的对象和传入的对象是同一个对象
            return true;          //直接返回rute    
        if (obj == null)          //传入的对象为null
            return false;          //返回false
        if (getClass() != obj.getClass()) //判断两个对象对应的字节码未见是否是同一个字节码
            return false;           //如果不是直接返回false
        Person other = (Person) obj;     //向下转型
        if (age != other.age)        //调用对象的年内不等于传入对象的年龄
            return false;           //返回false
        if (name == null) {          //调用对象的姓名不为null
            if (other.name != null)      //传入对象的姓名不为null
                return false;          //返回false
        } else if (!name.equals(other.name))  //调用对象的姓名不等于传入对象的姓名
            return false;              //返回flase
        return true;                 //返回true
    }
}

 

 

LinkedHashset

特点:

  可以保证怎么存就怎么取

底层是连带实现的,是set集合中唯一一个能保证怎么存怎么取得集合对象

因为Hashset的子类,所以也是保证元素唯一的,与Hashset的原理一样

 

随机数

public class test1 {

    public static void main(String[] args) {
        //创建Random类创建随机数对象
        Random r1=new Random();
        //不能重复,需要用Hashset方法
        HashSet<Integer> hs1=new HashSet<>();
        //hashset的size是下雨10就可以不断存储,如果大于等于10就停止存储
        while (hs1.size()<10) {
            //通过random类中的nextInt(n)方法获取1到20之间的随机数,并将这些随机数存现在hashset集合中
            hs1.add(r1.nextInt(21));
        }
        //遍历Hashset
        for (Integer integer : hs1) {
            System.out.println(integer);
        }
    }
练习题

键盘输入,去掉重复

import java.util.HashSet;
import java.util.Scanner;

import javax.sound.sampled.Line;

public class test2 {

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        
        System.out.println("请输入");    
        //创建Hashset独享,将字符存储,去掉重复
        HashSet<Character> hs1 =new HashSet<>();
        //将字符串转换成字符数组,获取每一个字符存储在Hashset集合中,自动去除重复
        String line=sc.nextLine();    
        char[] arr=line.toCharArray();
        
        for (char c : arr) { //遍历字符数组
            hs1.add(c);
        }
        //遍历Hashset,打印每一个字符
        for(Character ch:hs1){
            System.out.println(ch);
        }
    }

}
练习题

去除集合中的重复

import java.util.ArrayList;
import java.util.LinkedHashSet;

public class test3 {

    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("a");
        list.add("a");
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("c");
                        
        getSingle(list);    //调用方法
                
        System.out.println(list);

    }

    public static void getSingle(ArrayList<String> list) {
        LinkedHashSet<String> lsh=new LinkedHashSet<>();
        
        lsh.addAll(list); //添加list元素
        
        list.clear();        //清除list元素
        
        list.addAll(lsh);    //将LinkedHashset集合中的元素添加会list集合中
    }

}
练习题

 

TreeSet

Treeset存储Integer类型的元素并遍历

import java.util.TreeSet;

public class demo4_TreeSet {
    //TreeSet集合是用来对对象元素进行排序的,同事也可以保证元素的唯一
    public static void main(String[] args) {
        
        TreeSet<Integer> ts1=new TreeSet<>();
        ts1.add(1);
        ts1.add(1);
        ts1.add(2);
        ts1.add(2);
        ts1.add(3);
        ts1.add(3);
        ts1.add(3);
        ts1.add(4);
        ts1.add(4);
        
        System.out.println(ts1);

    }

}
案例

TreeSet存储自定义对象

 

二叉数:两个叉

 

小的存储在左边(负数),打的存储在右边(整数),相等就不存(0)

 

compareTo方法,在TreeSet集合如何存储元素取决于compareTo方法的返回值

 

返回0,集合中只有一个元素

 

返回负数集合会将存储的元素倒序

返回整数会怎么存怎么取

 

import java.util.Iterator;
import java.util.TreeSet;

import tan.jung.bean.Person;

    /*当compareTo方法返回0的时候集合中只有一个元素
     *当compareTo方法返回整数的时候集合会怎么存就怎么取
     *当compareTo方法返回负数的时候集合会倒序存储
     * */
public class demo5_TreeSet {
    public static void main (String args[]){
      TreeSet<Person> ts1=new TreeSet<>();
      ts1.add(new Person("xx",20));
      ts1.add(new Person("hh",20));      
      ts1.add(new Person("nn",20));
      ts1.add(new Person("mm",20));
      
      Iterator<Person> it1=ts1.iterator();
      while (it1.hasNext()) {
        Person p1=it1.next();
        System.out.println(p1.getName()+"  "+p1.getAge());
        
    }
      //System.out.println(ts1);
    }
    
}

//第二个包
public class Person implements Comparable<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) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    /*@Override
    public boolean equals(Object obj) {
        System.out.println("执行了");
        Person p=(Person)obj;
        return this.name.equals(p.name) && this.age == p.age;  
    }
    @Override
    public int hashCode() {
        final  int num=38;
        return name.hashCode() * num +age;
    }*/
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public int compareTo(Person o) {
        
        return -1;
    }
}
案例

 

按照姓名排序

按照年龄排序

import java.util.Iterator;
import java.util.TreeSet;

import tan.jung.bean.Person;

    /*当compareTo方法返回0的时候集合中只有一个元素
     *当compareTo方法返回整数的时候集合会怎么存就怎么取
     *当compareTo方法返回负数的时候集合会倒序存储
     * */
public class demo5_TreeSet {
    public static void main (String args[]){
      //demo1();
        TreeSet<Person> ts1=new TreeSet<>();
          ts1.add(new Person("张三",20));
          ts1.add(new Person("李四",12));      
          ts1.add(new Person("王五",25));
          ts1.add(new Person("赵六",11));
          ts1.add(new Person("七七",11));
          
          System.out.println('张'+0);
          System.out.println('李'+0);
          System.out.println('王'+0);
          System.out.println('赵'+0);
          System.out.println('七'+0);
          
          Iterator<Person> it1=ts1.iterator();
          while (it1.hasNext()) {
            Person p1=it1.next();
            System.out.println(p1.getName()+"  "+p1.getAge());
            
        }
    }

    public static void demo1() {
        TreeSet<Person> ts1=new TreeSet<>();
          ts1.add(new Person("xx",20));
          ts1.add(new Person("hh",12));      
          ts1.add(new Person("nn",25));
          ts1.add(new Person("mm",11));
          ts1.add(new Person("ss",11));
          
          Iterator<Person> it1=ts1.iterator();
          while (it1.hasNext()) {
            Person p1=it1.next();
            System.out.println(p1.getName()+"  "+p1.getAge());
            
        }
    }
    
}


//第二个包
import java.awt.RenderingHints;

public class Person implements Comparable<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) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    /*@Override
    public boolean equals(Object obj) {
        System.out.println("执行了");
        Person p=(Person)obj;
        return this.name.equals(p.name) && this.age == p.age;  
    }
    @Override
    public int hashCode() {
        final  int num=38;
        return name.hashCode() * num +age;
    }*/
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    /*@Override
    public int compareTo(Person o) {
        int num =this.age-o.age;  //年龄是主要条件
        return num==0 ? this.name.compareTo(o.name) : num;
    }*/
    @Override
    public int compareTo(Person o) {
        int num=this.name.compareTo(o.name); 
        int num2=this.age-o.age;//姓名是主要条件
        return num==0 ? num2 :num;
    }
    
}
案例

按照姓名长度排序

public int compareTo(Person o) {
        int length =this.name.length() - o.name.length();  //比较长度为主要条件
        int num =length == 0? this.name.compareTo(o.name) :length;//比较内容为次要条件
        //如果length等于0的话就比较this.name.compareTo(o.name) ,compare比较内容
        //如果不等于0的话就比较length
        return num ==0 ? this.age-o.age :num; //比较年龄为次要条件
    }
方法

 

接口不能直接new 需要给子类对象

public class demo5_TreeSet {
    public static void main (String args[]){  
        //demo1();
        //demo2();
        //demo3();
        TreeSet<String> ts1=new TreeSet<>(new CompareByLen());       
                 //compare c=new CompareByLen();
          ts1.add("abccd");
          ts1.add("z");
          ts1.add("bb");
          ts1.add("sss");
          System.out.println(ts1);
        
                
          
    }
}

class CompareByLen implements Comparator<String>{

    @Override
    public int compare(String s1, String s2) { //按照字符串的长度比较
        int num =s1.length() -s2.length();        //长度为主要条件
    
        return num == 0 ?s1.compareTo(s2) : num ; //内容为次要条件
    }
     
 }
案例

 

TreeSet原理

特点:

  TreeSet是用来排序的,可以指定一个顺序,对象存入之后会按照指定的顺序排列

使用方式:

  1.自然排序(Comparable)

    TreeSet类的add()方法中会把存入的对象提升为Comparable类型

    调用对象的compareTo()方法和集合中的对象比较

    根据compareTo()方法返回结果进行存储

  2.比较器顺序(Comparator)

    创建TreeSet的时候可以制定一个Comparatpr

    如果传入了Comparator的子类对象,那么TreeSet就会按照比较器中的顺序排序

    add()犯法内部会自动调用Comparator接口中compare()方法排序

    调用的对象是compare()方法的第一个参数,集合中的对象是compare方法的第二个参数

  3.两种方式区别:

    TreeSet构造函数什么都不传,默认按照类中Comparable的顺序(没有就报错ClassCasException)

    TreeSet如果传入了Comparator,就优先按照Comparator

posted @ 2019-05-28 02:49  JungTan0113  阅读(236)  评论(0编辑  收藏  举报