Collection接口(容器)中的Set接口;Set的3个实现类:HashSet ; LinkedHashSet;TreeSet

package day03;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**Set接口:
 * Set接口表示一个唯一、无序的容器(和添加顺序无关)
 * 
 *
 */
public class Set01 {
public static void main(String[] args) {
    /**Set接口提供的方法
     * 增:add/addAll
     * 删:clear/remove/removeAll/retainAll
     * 改:
     * 查:contains/containsAll
     * 遍历:iterator
     * 其他:size/isEmpty
     */
    
     Set<Integer> set=new HashSet<Integer>();
    // [1]添加
    // 无序
    set.add(10);
    set.add(20);
    set.add(30);
    set.add(1);
    set.add(0);
    // 不能添加重复元素
    boolean r=set.add(1);
    System.out.println(r);//输出结果:false(元素1没有重复添加进去)
    System.out.println(set);//输出结果:[0, 1, 20, 10, 30](元素是无序的)
    
    
    // 【2】删除
    set.remove(10);//删除元素10
    System.out.println(set);//输出结果:[0, 1, 20, 30]
    set.clear();//清空所有元素
    System.out.println(set);//输出结果:[]
    
    
    // 【3】查看是否包含
    System.out.println(set.contains(1));//输出结果:false
    
    
    // 【4】其他
    System.out.println(set.size());//输出结果:0(集合里有多少位元素)
    System.out.println(set.isEmpty());//输出结果:true(  如果 set 不包含元素,则返回 true。)
    
    
    
    
    set.add(10);
    set.add(20);
    set.add(30);
    set.add(1);
    set.add(0);
    
    
    // 快速遍历
    for (Integer item:set){
        System.out.println(item);//输出结果:0  1  20  10   30
    }
    
    // 迭代器
    
    Iterator<Integer> it= set.iterator();
        while(it.hasNext()){
            Integer item1=it.next();
            System.out.println(item1);//输出结果:0  1  20  10   30
        }
        
    
}
}
 
package day03;
//实现Comparable<Pen>
public class Pen implements Comparable<Pen>{
    private String name;
    private int health;
    private int love;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getHealth() {
        return health;
    }
    public void setHealth(int health) {
        if(health < 0) {
            this.health = 100;
            System.out.println("健康值不合法!");
        }else {            
            this.health = health;
        }
    }
    public int getLove() {
        return love;
    }
    public void setLove(int love) {
        this.love = love;
    }

    public Pen() {
        super();
        this.health = 100;
        this.love = 0;
    }
    /*为了比较自定义类的内容重写hashCode方法和equals方法(用编译器自动生成)
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + health;
        result = prime * result + love;
        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;
        Pen other = (Pen) obj;
        if (health != other.health)
            return false;
        if (love != other.love)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }*/
    
    
    
    public Pen(String name, int health, int love) {
        super();
        this.name = name;
        this.setHealth(health);
        this.setLove(love);
    }
    
    public void showInfo() {
        System.out.print("我的姓名:"+this.getName());
        System.out.print(",健康值:"+this.getHealth());
        System.out.print(",亲密度"+this.getLove());
    }
    //重写Object 方法
    @Override
    public String toString() {
        return "Pen [name=" + name + ", health=" + health + ", love=" + love
                + "]";
    }
    //重写compareTo方法(先比亲密度,在比较名字)
    /*内部比较器
     * 当一个自定义对象实现Comparable并实现compareTo方法时,通过指定具体的比较策略,此时称为内部比较器。
     * 比较策略的几种情况
         [1]比较策略一般当前对象写在前面,待比较对象也在后面,比较结果默认升序
                      如果想要降序,改变两个比较对象的位置即可。
         [2] 多种比较因素
     * */
    @Override
    public int compareTo(Pen a) {
        if (this.getLove()<a.getLove()){
            return -1;
        }else if(this.getLove()==a.getLove()){
            return this.getName().compareTo(a.getName());//string类型写法
        }else{
            return 1;
        }//简单写法:return this.getLove()-<a.getLove();
    }
}
 
 
 


package
day03; /**Set接口的实现类常见的有HashSet、LinkedHashSet、TreeSet * HashSet * HashSet是Set接口的实现类,底层数据结构是哈希表。 HashSet是线程不安全的(不保证同步) */ import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.TreeSet; public class Test { public static void main(String[] args) { /*添加自定义对象 如果向HashSet中存储元素时,元素一定要实现hashCode方法和equals方法。 优点:添加、删除、查询效率高;缺点:无序*/ HashSet<Pen> set=new HashSet<Pen>(); Pen d1 = new Pen("大狗",100,0); Pen d2 = new Pen("二狗",100,0); Pen d3 = new Pen("三狗",100,0); Pen d4 = new Pen("三狗",100,0); set.add(d1); set.add(d2); set.add(d3); //未重写前 System.out.println(set.add(d4));输出结果:true System.out.println(set.add(d4));//(在Pen用编译器自动生成重写方法)重写后输出结果:false //(因为哈希表中的hashCode方法和equals方法本质是比较地址,如果想比较元素内容,则要重写两个方法) System.out.println(set.toString()); //输出结果:[Pen [name=二狗, health=100, love=0], Pen [name=大狗, health=100, love=0], Pen [name=三狗, health=100, love=0]] //输出结果没有顺序 /*LinkedHashSet LinkedHashSet是Set接口的实现类,底层数据结构哈希表+链表 哈希表用于散列元素;链表用于维持添加顺序。 如果要添加自定义类的对象元素,也需要重写hashCode和equals方法。*/ LinkedHashSet<Integer> set2= new LinkedHashSet<Integer>(); // 添加的顺序则是元素的顺序(由链表来实现) set2.add(10); set2.add(90); set2.add(20); set2.add(0); set2.add(1); set2.add(11); set2.add(10);//因为上面已有10 ,所以未添加到 System.out.println(set2);//输出结果:[10, 90, 20, 0, 1, 11] LinkedHashSet<Pen> set3= new LinkedHashSet<Pen>(); Pen d5 = new Pen("大狗",100,0); Pen d6 = new Pen("二狗",100,0); Pen d7 = new Pen("三狗",100,0); set3.add(d5); set3.add(d6); set3.add(d7); System.out.println(set3); //输出结果:[Pen [name=大狗, health=100, love=0], Pen [name=二狗, health=100, love=0], Pen [name=三狗, health=100, love=0]] /*1.12TreeSet TreeSet 是Set接口的实现类,底层数据结构是二叉树。 TreeSet 存储的数据按照一定的规则存储。存储规则让数据表现出自然顺序。 根据TreeSet的工作原理,向TreeSet添加自定义元素? 向TreeSet中添加元素时,一定要提供比较策略,否则会出现ClassCastException。 比较策略分两种:内部比较器和外部比较器 内部比较器(在Pen类中) 因为有时候我们不能访问源代码时,就要用到外部比较器 */ TreeSet<Pen> set4=new TreeSet<Pen>(); Pen d8 = new Pen("A",10,5); Pen d9 = new Pen("B",100,5); Pen d10 = new Pen("C",150,1); set4.add(d8); set4.add(d9); set4.add(d10); System.out.println(set4);//(先比亲密度,在比较名字,升序降序可自己调)( 内部比较器(在Pen类中)) //[Pen [name=C, health=150, love=1], Pen [name=A, health=10, love=5], Pen [name=B, health=100, love=5]] //使用外部比较器;需求:按照字符串的长度比较 Len len=new Len(); TreeSet<String> len1 = new TreeSet<String>(len); /*使用匿名内部类优化: * TreeSet<String> len1 = new TreeSet<String>(new Comparator<String>); * public int compare(String o1, String o2) { * // return o1.length() - o2.length(); // 如果长度一样,按照自然顺序 if(o1.length() == o2.length()) { return o1.compareTo(o2); }else { return o1.length() - o2.length(); } } len1.add("banana"); len1.add("coco"); len1.add("apple"); len1.add("apple"); System.out.println(len1);//输出结果:[coco, apple, banana] * */ len1.add("banana"); len1.add("coco"); len1.add("apple"); len1.add("apple"); System.out.println(len1);//输出结果:[coco, apple, banana] } } /*外部比较器 * 当实际开发过程中不知道添加元素的源代码、无权修改别人的代码,此时可以使用外部比较器。 Comparator 位于java.util包中,定义了compare(o1,o2) 用于提供外部比较策略 。 TreeSet接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现Comparator接口。 需求:按照字符串的长度比较 * */ class Len implements Comparator<String>{ @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } }

 注意: LinkedHashSet实现类中的方法hashCode和equals方法本质是比较地址,如果要比较内容,则要重写hashCode和equals方法(去掉自定义类中重复内容的对象);

;TreeSet 类中如果以自定义类来作为Key的话,要自己写比较条件(要排序),

哈希表:

二叉树

猜你喜欢

转载自www.cnblogs.com/406070989senlin/p/10817011.html