集合-3

来源:互联网 发布:apache下载安装 win7 编辑:程序博客网 时间:2024/06/03 19:13


集合-3

1.HashSet存储字符串并遍历

* A:Set集合概述及特点

         *通过API查看即可

         *Set集合,无索引,不可以重复,无序(存取不一致)

* B:案例演示

         *HashSet存储字符串并遍历

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

                   booleanb1 = hs.add("a");

                   booleanb2 = hs.add("a"); 

                           

                   System.out.println(b1);

                   System.out.println(b2);   //当向set集合中存储重复元素的时候,返回false

                   for(Strings : hs) {

                            System.out.println(s);  //输出是无序的,不是存入的顺序!!

                   }

 

2.HashSet存储自定义对象保证元素唯一性图解及代码优化

* 代码优化

         *为了减少比较,优化hashCode()代码写法。

         *最终版就是自动生成即可。

 

3.HashSet如何保证元素唯一性的原理

* 1.HashSet原理

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

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

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

                   *如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存,只有两个对象的hashcode值一样,它才会去调用equals方法作比较

* 2.将自定义类的对象存入HashSet去重复

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

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

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

* A:案例演示

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

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

                            hs.add(newPerson("张三", 23));

                            hs.add(newPerson("张三", 23));    @@当你添加对象的时候会自动调用hashcode方法,当hashcode值一样的时候它就会去掉调用equals方法

                            hs.add(newPerson("李四", 23));   

                            hs.add(newPerson("赵六", 23));

 

4.LinkedHashSet的概述和使用

* LinkedHashSet的特点

         *可以保证怎么存就怎么取

       * 底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象

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

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

                   lhs.add("a");

                   lhs.add("b");

                   lhs.add("b");

                   lhs.add("c");             

                   System.out.println(lhs);   //输出[a,b,c,]

 

5.编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。

          * 分析:

          * 1,有Random类创建随机数对象

          * 2,需要存储10个随机数,而且不能重复,所以我们用HashSet集合

          * 3,如果HashSet的size是小于10就可以不断的存储,如果大于等于10就停止存储

          * 4,通过Random类中的nextInt(n)方法获取1到20之间的随机数,并将这些随机数存储在HashSet集合中

          * 5,遍历HashSet

                   HashSet<Integer>hs = new HashSet<>();                //创建集合对象

                   Randomr = new Random();     //创建随机数对象

                           

                   while(hs.size()< 10) {

                            intnum = r.nextInt(20) + 1;      //生成1到20的随机数

                            hs.add(num);     @@自动装箱

                   }                          

                   for(Integer integer : hs) {                  //遍历集合

                            System.out.println(integer);   //打印每一个元素

                   }

 

6.集合框架(练习)

* 使用Scanner从键盘读取一行输入,去掉其中重复字符, 打印出不同的那些字符,aaaabbbcccddd

          * 分析:

          * 1,创建Scanner对象

          * 2,创建HashSet对象,将字符存储,去掉重复

          * 3,将字符串转换为字符数组,获取每一个字符存储在HashSet集合中,自动去除重复

          * 4,遍历HashSet,打印每一个字符

                   Scannersc = new Scanner(System.in);             //创建键盘录入对象

                   System.out.println("请输入一行字符串:");

                   Stringline = sc.nextLine();          //将键盘录入的字符串存储在line中

                   char[]arr = line.toCharArray();        //将字符串转换成字符数组

                   HashSet<Character>hs = new HashSet<>();  //创建HashSet集合

                           

                   for(charc : arr) {                //遍历字符数组

                            hs.add(c);                   //将字符数组中的字符添加到集合中

                   }

                           

                   for(Character ch : hs) {   //遍历集合,同样这里写成char,也可以,叫自动拆箱

                            System.out.println(ch);

                   }

7.集合框架(练习)

* 将集合中的重复元素去掉  (两种方法,另一种是创建新集合的方式!!!)

*                *  分析:

                    *  1,创建List集合存储若干个重复元素

                    *  2,单独定义方法去除重复

                    *  3,打印一下List集合

                            publicstatic void main(String[] args) {

                                     ArrayList<String>list = new ArrayList<>();

                                     list.add("a");

                                     list.add("b");

                                     list.add("b");

                                     list.add("c");

                                     list.add("c");

 

                                     getSingle(list);

                                     System.out.println(list);

                            }                          

                             * 分析

                           * 去除List集合中的重复元素

                             * 1,创建一个LinkedHashSet集合

                             * 2,将List集合中所有的元素添加到LinkedHashSet集合

                             * 3,将list集合中的元素清除

                             * 4,将LinkedHashSet集合中的元素添加回List集合中

 

                            publicstatic void getSingle(List<String> list) {

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

                                     lhs.addAll(list);         //将list集合中的所有元素添加到lhs

                                     list.clear();                 //清空原集合

                                     list.addAll(lhs);         //将去除重复的元素添回到list中

                            }

 

8.TreeSet存储Integer类型的元素并遍历

* TreeSet存储Integer类型的元素并遍历    @@TreeSet底层是二叉树

     *会去除重复元素,并排好序输出

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

                   ts.add(3);

                   ts.add(1);

                   ts.add(1);

                   ts.add(2);                  

                   System.out.println(ts);//输出[1,2,3]!!!!!

9.集合框架()

* TreeSet存储自定义对象

         当向TreeSe集合中添加自定义对象时会报错,所以person这个类必须实现Comparable接口,并重写里面的compareTo方法才可以;  另外,当你向TreeSet中添加对象时,它会自动调用compareTo方法,并根据compareTo的返回值决定如何存储元素.

* TreeSet存储自定义对象并遍历练习1(按照姓名排序)

* TreeSet存储自定义对象并遍历练习2(按照姓名的长度排序)

附:Person.java

public class Person implementsComparable<Person> {

         privateString name;

         privateint age;

         publicPerson() {

                   super();

                  

         }

         publicPerson(String name, int age) {

                   super();

                   this.name= name;

                   this.age= age;

         }

         @Override

         publicString toString() {

                   return"Person [name=" + name + ", age=" + age + "]";

         }

         @Override

         publicboolean equals(Object obj) {

                   Personp = (Person)obj;

                   returnthis.name.equals(p.name) && this.age == p.age;

         }

         @Override

         publicint hashCode() {

                   finalint NUM = 38;

                   returnname.hashCode() * NUM + age;      //要尽可能的让hashcode的值不同,这样就可以少调用equals方法,提高运行效率; 在开发的时候hashcode和equals方法不用自己写,alt+shift+s

         }

         按照年龄排序

         publicint compareTo(Person o) {

                   intnum = this.age - o.age;       //年龄是比较的主要条件

                   returnnum == 0 ? this.name.compareTo(o.name) : num;//姓名是比较的次要条件,num大于0或小于0都返回num,等于0返回名字的比较结果,这里的compareTo是string中的方法,被重写了,按照字典顺序比较!!!!!!

         }

         按照姓名排序

         publicint compareTo(Person o) {

                   intnum = this.name.compareTo(o.name);               //姓名是主要条件

                   returnnum == 0 ? this.age - o.age : num;       //年龄是次要条件,如果姓名一样,返回年龄差,否则返回num

         }

 

         publicint compareTo(Person o) {

                   intlength = this.name.length() - o.name.length();  //比较长度为主要条件

                   intnum = length == 0 ? this.name.compareTo(o.name) : length;  //比较内容为次要条件

                   returnnum == 0 ? this.age - o.age : num;       //比较年龄为次要条件

         }       

}

 

* TreeSet保证元素唯一和比较器排序的原理及代码实现

public static void main(String[] args) {

                   //需求:将字符串按照长度排序

                   TreeSet<String>ts = new TreeSet<>(new CompareByLen()); //Comparator c = new CompareByLen();

                   ts.add("aaaaaaaa");

                   ts.add("z");

                   ts.add("wc");;          

                   System.out.println(ts);

         }

class CompareByLen /*extends Object*/implements Comparator<String> {

 

         @Override

         publicint compare(String s1, String s2) {                   //按照字符串的长度比较

                   intnum = s1.length() - s2.length();           //长度为主要条件

                   returnnum == 0 ? s1.compareTo(s2) : num;   //内容为次要条件

         }

10.TreeSet原理

* 1.特点

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

* 2.使用方式

         *a.自然顺序(Comparable)需要你存储的这个类去实现Comparable接口,并重写里面的Comparable方法

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

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

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

         *b.比较器顺序(Comparator)

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

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

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

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

         *c.两种方式的区别

                   *TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)类型转换异常

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

 

11.集合框架(练习)

* 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复

                           * 分析:

                             * 1,定义一个List集合,并存储重复的无序的字符串

                           * 2,定义方法对其排序保留重复

                             * 3,打印List集合

 

                            publicstatic void main(String[] args) {

                                     ArrayList<String>list = new ArrayList<>();

                                     list.add("ccc");

                                     list.add("ccc");

                                     list.add("aaa");

                                     list.add("aaa");

                                     list.add("bbb");;

                                     list.add("ddd");

                                    

                                     sort(list);

                                     System.out.println(list);

                            }

                           

                             * 定义方法,排序并保留重复

                             * 分析:

                             * 1,创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器

                             * 2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复

                             * 3,清空list集合

                             * 4,将TreeSet集合中排好序的元素添加到list中

                            publicstatic void sort(List<String> list) {

                                     TreeSet<String>ts = new TreeSet<>(new Comparator<String>() {                   //定义比较器(newComparator(){}是Comparator的子类对象)

                  

                                               @Override

                                               publicint compare(String s1, String s2) {                                                        //重写compare方法

                                                        intnum = s1.compareTo(s2);                                                                             //比较内容

                                                        returnnum == 0 ? 1 : num;                                                                                 //如果内容一样返回一个不为0的数字即可

                                               }

                                     });

                                    

                                     ts.addAll(list);  //将list集合中的所有元素添加到ts中

                                     list.clear();         //清空list

                                     list.addAll(ts);  //将ts中排序并保留重复的结果在添加到list中

                            }

 

12.集合框架(练习)

* 从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入:helloitcast程序打印:acehillostt

                * 分析:

                   *1,键盘录入字符串,Scanner

                 * 2,将字符串转换为字符数组

                 *3,定义TreeSet集合,传入比较器对字符排序并保留重复

                 *4,遍历字符数组,将每一个字符存储在TreeSet集合中

                 *5,遍历TreeSet集合,打印每一个字符

 

                   Scannersc = new Scanner(System.in);    //创建键盘录入对象

                   System.out.println("请输入一行字符串:");

                   Stringline = sc.nextLine();                 //将键盘录入的字符串存储在line中

                   char[]arr = line.toCharArray();        //将字符串转换成字符数组

                   TreeSet<Character>ts = new TreeSet<>(new Comparator<Character>() {

 

                            @Override

                            publicint compare(Character c1, Character c2) {

                                     //intnum = c1.compareTo(c2);  //1

                                     intnum = c1 - c2;           // 2 自动拆箱!!!!!!!! 1,2意思相同

                                    returnnum == 0 ? 1 : num;

                            }

                   });

                  

                   for(charc : arr) {

                            ts.add(c);  //自动装箱

                   }

                  

                   for(Characterch : ts) {

                            System.out.print(ch);

                   }

13.集合框架(练习)

* 程序启动后,可以从键盘输入接收多个整数,直到输入quit时结束输入. 把所有输入的整数倒序排列打印.

   *1,创建Scanner对象,键盘录入

   *2,创建TreeSet集合对象,TreeSet集合中传入比较器

   *3,无限循环不断接收整数,遇到quit退出,因为退出是quit,所以键盘录入的时候应该都以字符串的形式录入

   *4,判断是quit就退出,不是就将其转换为Integer,并添加到集合中

   *5,遍历TreeSet集合并打印每一个元素

         Scannersc = new Scanner(System.in);             //创建键盘录入对象

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

         TreeSet<Integer>ts = new TreeSet<>(new Comparator<Integer>() {//将比较器传给TreeSet的构造方法

        

                   @Override

                   publicint compare(Integer i1, Integer i2) {

                            //intnum = i2 - i1;    //自动拆箱,正序就i1-i2!!!!!!!

                            intnum = i2.compareTo(i1);

                            returnnum == 0 ? 1 : num;

                   }

         });

                           

         while(true){

                   Stringline = sc.nextLine();  //将键盘录入的字符串存储在line中

                   if("quit".equals(line))       {        //如果字符串常量和变量比较,常量放前面,这样不会出现空指针异常,变量里面可能存储null

                            break;

                   try{

                            intnum = Integer.parseInt(line);//将数字字符串转换成数字

                            ts.add(num);

                   }catch (Exception e) {

                            System.out.println("您录入的数据有误,请输入一个整数");

                   }                                   

         }

                           

         for(Integer i : ts) {            //遍历TreeSet集合

                   System.out.println(i);

         }

14.键盘录入学生信息按照总分排序后输出在控制台

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

         *分析:

         *1,定义一个学生类

         *     成员变量:姓名,语文成绩,数学成绩,英语成绩,总成绩

         *     成员方法:空参,有参构造,有参构造的参数分别是姓名,语文成绩,数学成绩,英语成绩

        *                 toString方法,在遍历集合中的Student对象打印对象引用的时候会显示属性值

        * 2,键盘录入需要Scanner,创建键盘录入对象

        * 3,创建TreeSet集合对象,在TreeSet的构造函数中传入比较器,按照总分比较

         *4,录入五个学生,所以以集合中的学生个数为判断条件,如果size是小于5就进行存储

         *5,将录入的字符串切割,用逗号切割,会返回一个字符串数组,将字符串数组中从二个元素转换成int数,

         *6,将转换后的结果封装成Student对象,将Student添加到TreeSet集合中

         *7,遍历TreeSet集合打印每一个Student对象

------------------------------------------------------------------------------------------

                   Scannersc = new Scanner(System.in);

                   System.out.println("请输入5个学生成绩格式是:(姓名,语文成绩,数学成绩,英语成绩)");

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

                            @Override

                            publicint compare(Student s1, Student s2) {

                                     intnum = s2.getSum() - s1.getSum();      //根据学生的总成绩降序排列

                                     returnnum == 0 ? 1 : num;

                            }

                   });

                           

                   while(ts.size()< 5) {

                            Stringline = sc.nextLine();

                            try{

                                     String[]arr = line.split(",");

                                     intchinese = Integer.parseInt(arr[1]);    //转换语文成绩

                                     intmath = Integer.parseInt(arr[2]);         //转换数学成绩

                                     intenglish = Integer.parseInt(arr[3]);     //转换英语成绩

                                     ts.add(newStudent(arr[0], chinese, math, english));

                            }catch (Exception e) {

                                     System.out.println("录入格式有误,输入5个学生成绩格式是:(姓名,语文成绩,数学成绩,英语成绩");

                            }

                                    

                  }

                           

                   System.out.println("排序后的学生成绩是:");

                   for(Student s : ts) {

                            System.out.println(s);

                   }

 

15.总结

* 1.List

         *a.普通for循环, 使用get()逐个获取

         *b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法

         *c.增强for循环, 只要可以使用Iterator的类都可以用

         *d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法

* 2.Set

         *a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法

         *b.增强for循环, 只要可以使用Iterator的类都可以用

* 3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除


0 0
原创粉丝点击