day15Set接口

来源:互联网 发布:java布尔类型的常量 编辑:程序博客网 时间:2024/06/06 23:12

Set接口:Set集合继承Collection集合

Set:底层的数据结构是一个哈希表,保证元素唯一,元素不重复

通过子实现类HashSet集合去实例化,Hashset集合底层是HashMap集合的实例!

//利用ser集合存储字符串元素并遍历,证明元素唯一

Eg:

import java.util.HashSet;

import java.util.Set;

public class SetDemo {

public static void main(String[] args) {

    Set<String> set=new HashSet<String>();

    set.add("faker");

    set.add("Uzi");

    set.add("Margen");

    set.add("Uzi");

    set.add("Uzi");

    set.add("Uzi");

    for(String s:set){

    System.out.println(s);

    }

}

}

输出结果为

Uzi

Magren

faker

 证明了set集合元素的唯一性,元素不重复.

 

Set集合的子实现类

实现Set接口,由哈希表(实际是一个hashMap)支持.不保证set的迭代顺序,不能保证顺序不发生变化.

 

HashSet集合的add方法,底层依赖于双列集合HashMap<K,V>的put(K key,V value)实现的

put(K key,Vvalue):这个方法底层又依赖于equals()和hashCode()方法.首先比较地址值是否相同,当地址值相同后再用equals方法比较值是否相同.此时保存的是String类型.因为equals方法默认比较的是地址值.重写后比较的是值是否相同.String类型默认重写了equals方法.当内容相同时,返回第一次存储的元素,以此保证元素的唯一性.  

put(K key,V value)键值对   

一个对象key 对应一个value  都存储值, 一个key和value对应一个地址值.

 

import java.util.HashSet;

public class HashDemo {

public static void main(String[] args) {

    HashSet<String> hs=new HashSet<String>();

    hs.add("RNG");

    hs.add("RNG");

    hs.add("RNG");

    hs.add("WE");

    hs.add("WE");

    hs.add("SKT");

    for(String s:hs){

       System.out.println(s);

    }

}

}

 

需求:使用Hash存储自定义对象并遍历

List与Set集合的区别?

Set集合:元素唯一,无序性(存取不一致)

List集合:元素可以重复,且有序(存取一致)

 

创建学生对象:

import java.util.HashSet;

public class HashSetDemo {

public static void main(String[] args) {

    HashSet<Student>hs=new HashSet<Student>();

    Student s1=new Student("小虎",22);

    Student s2=new Student("小狗",20);

    Student s3=new Student("大魔王",21);

    Student s4=new Student("五五开",23);

    Student s5=new Student("小虎",22);

    hs.add(s1);

    hs.add(s2);

    hs.add(s3);

    hs.add(s4);

    hs.add(s5);

    for(Student s:hs){

    System.out.println(s.getName()+"--"+s.getAge());

    }

}

}

Student类必须重写equals()方法和HashCode()

输出结果:

大魔王--21

五五开--23

小狗--20

小虎--22

HashCode返回地址值. 当值相同时,地址值也相同

public class HashSetDemo1 {

    public static void main(String[] args) {

           System.out.println("Uzi".hashCode());

           System.out.println("Faker".hashCode());

           System.out.println("Margrn".hashCode());

           System.out.println("AAA".hashCode());

           System.out.println("AAA".hashCode());

       }

    }

 

 

LinkedHashSet集合:由哈希表保证元素的唯一性,链接列表保证元素的有序性.

import java.util.LinkedHashSet;

public class LinkHashSetDemo {

public static void main(String[] args) {

    LinkedHashSet<String>link=new LinkedHashSet<String>();

    link.add("Uzi");

    link.add("Uzi");

    link.add("Uzi");

    link.add("faker");

    link.add("faker");

    link.add("Margin");

    for(Strings:link){

    System.out.println(s);

    }

}

}

输出为:

Uzi           //该集合保证数据的唯一性和有序性

faker

Margin

 

Random:产生一个随机数的类:

构造方法:publicRandom()创建一个新的随机数生成器

成员方法:public intnextInt():有随机数生成器调用方法,随机数的范围在

int类型的范围之内

public int nextint(int n):生成随机数的范围:[0,n):使用比较多

包含左,不包含右

 

eg:

import java.util.Random;

public class RandomText {

public static void main(String[] args) {

    Random r=new Random();

    for(int x=0;x<10;x++){

       int number=r.nextInt();

       int number1=r.nextInt(20)+1;

//     System.out.println(number);

       System.out.println(number1);

    }

}

}

 

练习:生成10个1到20之间的随机数,不能重复.

1.  创建一个随机数生成器

2.  使用ArrayList存储:类型Integer

3.  定义统计变量count

4.  判断如果统计变量小于10    通过随机数获取1-20间的数

判断集合是否有 ,不包含则添加这些随机数,不包含,添加集合count++

5.  遍历集合

eg:

import java.lang.reflect.Array;

import java.util.ArrayList;

import java.util.Random;

public class RandomText1 {

public static void main(String[] args) {

    Random r=new Random();

    //创建集合

    ArrayList<Integer>arr=newArrayList<Integer>();

    int count=0;

    while(count<10){

       int number=r.nextInt(20)+1;

       if(!arr.contains(number)){ //判断是否包含

       arr.add(number);

       count++;

       }

    }

    for(Integer i:arr){

       System.out.print(i+" ");

    }

 }

}

 

TreeSet:Set集合中重点

TreeSet集合底层依赖TreeMap的实例,TreeMap<K,V>依赖于红黑树实现

两种方法: 自然排序 比较器排序

取决于使用的构造方法:

自然排序:

import java.util.TreeSet;

public class TreeSetDemo {

public static void main(String[] args) {

       //public TreeSet():无参构造:根据其元素的自然顺序进行排序

       TreeSet<Integer> ts = new TreeSet<Integer>();

       //20,18,23,22,17,24,19,18,24

       ts.add(20);// Integer i =Integer.valueOf(20) ;

       ts.add(18) ;

       ts.add(23) ;

       ts.add(22) ;

       ts.add(17) ;

       ts.add(24) ;

       ts.add(19) ;

       ts.add(18) ;

       ts.add(24) ;

       for(Integer i : ts){

           System.out.print(i+" ");//17 18 19 20 2223 24 :唯一并且排序:自然排序(升序排序)

       }

    }

}

输出结果: 17 18 1920 22 23 24

 

红黑树结构:二叉树结构,一种自平衡的二叉树结构

红黑树结构在存储元素时,第一次存储元素作为根节点.后面以此存储元素,

与根节点进行比较,如果小了,左孩子.  大了,右孩子. 

当相等时,不用管.

 

排序:依赖于TreeMap<k,V>中的put<K key, V value>

按照自然顺序输出

对于TreeSet集合要实现自然排序,那么该集合该集合中存储自定义类型必须实现一个接口:Comparable,并且重写该接口中的compareTo()方法

使用TreeSet集合存储自定义对象并遍历.

 

按照学生的年龄从小到大进行排序:主要条件

    对于自定义对象什么情况下保证元素是唯一的

成员变量的值相同,认为是同一个元素

次要条件 姓名内容长度

 

import java.util.TreeSet;

public class TreeSetDemo2 {

public static void main(String[] args) {

       //创建TreeSet集合对象

       TreeSet<Student> ts = new TreeSet<Student>() ;//

       //创建学生对象

       Student s1 = new Student("wuwenlong", 20) ;

       Student s2 = new Student("yangqilong", 21) ;

       Student s3 = new Student("dengcong", 22) ;

       Student s4 = new Student("pengkai",25) ;

       Student s5 = new Student("yangxiaozhou", 18) ;

       Student s6 = new Student("qiyuan", 22) ; ;

       ts.add(s1);

       ts.add(s2);

       ts.add(s3);

       ts.add(s4);

       ts.add(s5);

       ts.add(s6);

       for(Student s : ts){

           System.out.println(s.getName()+"---"+s.getAge());

       }

    }  

}

 

Student类

要实现自然排序,就必须实现Compareable接口

Student重写compareTo方法

@Override

public int compareTo(Students) {

    //主要条件:按照年龄从小到大进行排序

    int num =s.age -this.age ;

    //num==0认为年龄一样要,给出自然条件,比较长度

    int num2 = num==0 ?this.name.compareTo(s.name): num ;

    return num2 ;

}

}

 

 

比较器排序

依赖于构造方法: public TreeSet()Compare<E> comparator

两种方法实现比较器排序.

Comparator接口作为形参,需要接口的子实现类

方式一:自定义一个类,类实现CompareTo接口,作为子实现类

方式二:可以使用接口的匿名内部类来实现:开发中,由于减少代码书写量,不需要自定义接口的子实现类,直接这种格式!

格式

new 接口名或者类名(){

重写方法() ;

 }

1.通过Comparetor接口的子实现类实现

Eg:

public class MyComparatorimplements Comparator<Student> {

@Override

    public int compare(Student s1, Student s2) {

//     按照学生姓名长度从小到大进行排序

        int num =s1.getName().length() - s2.getName().length() ;

       //次要条件:姓名长度一样,还要比较姓名的内容是否一样

       int num2 = num==0 ? s1.getName().compareTo(s2.getName()): num;

       //姓名长度和内容都一样,还需比较两个人的年龄是否一样

       int num3 = num2 ==0 ? s1.getAge() - s2.getAge() : num2 ;

       return num3 ;

    }

}

2.匿名内部类

TreeSet<Student> ts = newTreeSet<Student>(new Comparator<Student>() {

@Override

           public int compare(Student s1, Student s2) {

             //里面写条件   

  }

}) ;

 

练习题: 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

首先定义一个Student类  提供姓名,语文,数学,英语等成员变量.并且提供一个getsun()

获取总分的方法.

创建创建TreeSet集合对象:TreeSet<Student>(Comparator<Student>com)集合

写出条件

录入成绩 for循环输出

Eg:

import java.util.Comparator;

import java.util.Scanner;

import java.util.TreeSet;

public class TreeSetDemo1 {

public static void main(String[] args) {

    TreeSet<Student> ts = new TreeSet<Student>(newComparator<Student>() {

        @Override

       public int compare(Student s1, Student s2) {

           int num = s2.getSum() - s1.getSum();//总分排序

           //比较语文成绩

           int num2 = num == 0 ? s1.getChinese() - s2.getChinese() :num;

            //比较数学成绩

           int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;

            //比较英语成绩

           int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() :num3;

            // 当其他相同时比计较姓名内容是否相同

           int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())

                  : num4;

           return num5;     

           }

    });

    System.out.println("请输入成绩:");

    for (int x = 1; x <= 5; x++) {

       // 创建键盘录入对象

       // 为了方便录入数据,数据类型都使用String类型接收

       Scanner sc = new Scanner(System.in);

       System.out.println("请输入第" + x +"个学生的姓名:");

        String name =sc.nextLine();

       System.out.println("请输入第" + x +"个学生的语文成绩:");

       String chineseString = sc.nextLine();

       System.out.println("请输入第" + x +"个学生的数学成绩:");

       String mathString = sc.nextLine();

       System.out.println("请输入第" + x +"个学生的英语成绩:");

       String englishString = sc.nextLine();

       Student s = new Student();

       s.setName(name);

       s.setChinese(Integer.parseInt(chineseString));

       s.setMath(Integer.parseInt(mathString));

       s.setEnglish(Integer.parseInt(englishString));

       ts.add(s);

    }

    System.out.println("成绩录入结束:");

    System.out.println("学生成绩如下:");

    System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");

    // 增强for遍历集合

    for (Student s : ts) {

       System.out.println(s.getName() +"\t" + s.getChinese() + "\t"

              + s.getMath() + "\t" + s.getEnglish());

    }

}

}

输出结果

姓名    语文成绩 数学成绩 英语成绩

吴文龙  100 100 100

杨启龙  99  100 100

邓聪        99  100 100

彭楷        100 99  99

杨晓洲  98  100 99