Java/11.12日/笔记

来源:互联网 发布:雅马哈电子琴入门 知乎 编辑:程序博客网 时间:2024/06/16 02:20

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

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

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

 需求:Set集合存储字符串元素并遍历

import java.util.HashSet;import java.util.Set;public class SetDemo {public static void main(String[] args) {//创建Set集合对象Set<String> set = new HashSet<String>() ;//添加元素set.add("hello");set.add("java") ;set.add("java") ;set.add("world") ;set.add("world") ;set.add("world") ;//增强for遍历for(String s :set){System.out.println(s);}}}2 hashcodepublic class HashCodeDemo {public static void main(String[] args) {System.out.println("hello".hashCode());System.out.println("hello".hashCode());System.out.println("world".hashCode());System.out.println("world".hashCode());/** * 9916232299162322113318802113318802 */}}

3 需求:使用HashSet集合存储自定义对象并遍历

 List集合和Set集合的区别?

 Set:元素是唯一的,无序性(存储和取出不一致)

 List:元素可以重复,有序性(存储和取出一致)

 由于现在是自定义对象:在当前自定义对象的类中没有重写两个方法

 hashCode和equals()方法;HashSet底层是依赖于这两个实现来保证元素的唯一性!

public class HashSetDemo {public static void main(String[] args) {//创建一个HashSet集合对象HashSet<Student> hs = new HashSet<Student>() ;//创建学生对象Student s1 = new Student("WDG", 24) ;Student s2 = new Student("RNG, 25) ;Student s3 = new Student("JHD", 26) ;//给集合中添加学生对象hs.add(s1) ;hs.add(s2) ;hs.add(s3) ;;//增强for遍历for(Student s : hs){System.out.println(s.getName()+"---"+s.getAge());}}}

4

  Set集合的子实现类:

  此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;

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

 put(K key,V value):

 底层又依赖于HashCode()和equals()方法,传递添加元素的时候,首先判断的是

 每一个元素对应的HashCode值是否一样,如果HashCode值一样,还比较他们的equals()方法,由于现在集合存储的是String类型,String类型本身重写了equals()方法,所以,默认比较的是内容是否相同,如果内容相同,这里最终返回的就是第一次存储的那个元素,由这两个方法保证元素唯一性!

import java.io.Serializable;import java.util.HashSet;public class SetDemo implements Serializable{//private int num ;//setDemo.class 固定id=100 transient int num ;public static void main(String[] args) {//创建HashSet集合对象HashSet<String> hs = new HashSet<String>();//给该集合中添加元素hs.add("hello") ;hs.add("world") ;hs.add("world") ;hs.add("Java") ;hs.add("Java") ;//遍历for(String s :hs){System.out.println(s);}}}

5具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

LinkedHashSet集合:

由哈希表保证元素的唯一性

由链接列表来保证元素的有序性!

import java.util.LinkedHashSet;public class LinkedHashSetDemo {public static void main(String[] args) {//创建LinkedHashSet集合对象LinkedHashSet<String> link = new LinkedHashSet<String>();//给集合中添加元素link.add("hello") ;link.add("world") ;link.add("world") ;link.add("Java") ;link.add("Java") ;link.add("JavaWeb") ;link.add("JavaWeb") ;//遍历集合for(String s: link){System.out.println(s);}}}

6 TreeSet:Set集合中的一个重点 

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

分两种:          

自然排序:

比较器排序

这种排序的使用取决于开发者是用什么样的构造方法

 TreeSet存储Integer类型添加以下元素

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

import java.util.TreeSetpublic class TreeSetDemo {public static void main(String[] args){//throw new IOException();//创建TreeSet集合对象//构造方法://public TreeSet():无参构造:根据其元素的自然顺序进行排序//publict TreeSet(Comparaptr<E> com)TreeSet<Integer> ts = new TreeSet<Integer>();////添加元素//20,18,23,22,17,24,19,18,24ts.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遍历for(Integer i : ts){System.out.print(i+ " ");//17 18 19 20 22 23 24 :唯一并且排序:自然排序(升序排序)}}}

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

实现了compareable接口,重写了comapreTo()方法,里面的逻辑是一个排序条件:

需求:

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

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

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

主要条件给定,需要分析次要条件

一个类中的元素想要自然排序,那么必须实现Compareable接口,实现compareTo(类名 对象名){}方法

按照正常存储对象的操作以及遍历对象出现了问题:

 类转换异常

* java.lang.ClassCastException: org.westos_04.Studentcannot be cast to java.lang.Comparable

 

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

import java.util.TreeSet;public class TreeSetDemo2 {public static void main(String[] args) {//创建TreeSet集合对象TreeSet<Student> ts = new TreeSet<Student>() ;////创建学生对象Student s1 = new Student("linqingxia", 28) ;Student s2 = new Student("fengqingy", 28) ;Student s3 = new Student("gaoyuanyuan", 27) ;Student s4 = new Student("liushishi", 26) ;Student s5 = new Student("wanglihong", 29) ;Student s6 = new Student("zhangguorong", 30) ;Student s7 = new Student("zhangguorong", 30) ;ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);ts.add(s7);//遍历for(Student s : ts){System.out.println(s.getName()+"---"+s.getAge());}}}//MyComparatpr是Comparator接口的子实现类import java.util.Comparator;public class MyComparator implements Comparator<Student> {public int compare(Student s1, Student s2) {//return 0;//int num = this.name.lengt()-s.name.length();//this--:s1//s---:s2int 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 ;}}  //元素唯一性:取决返回值是否为0 要使用TreeSet集合的比较器排序:依赖于构造方法:public TreeSet(Comparator<E> comparator)两种方式实现比较器排序:Comparator接口作为形式参数进行传递,需要该接口的子实现类对象import java.util.Comparator;import java.util.TreeSetpublic class TreeSetDemo {public static void main(String[] args) {//创建TreeSet集合使用比较器进行给元素进行排序//public TreeSet(Comparator<E> comparator):有参构造//方式1:自定义一个类,类实现Comparator接口,作为子实现类//方式2:可以使用接口的匿名内部类来实现:/**  格式  new 接口名或者类名(){ 重写方法() ;  }  *///TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {public int compare(Student s1, Student s2) {//return 0;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 ;}}) ;//创建学生对象Student s1 = new Student("gaoyuanyan", 27) ;Student s2 = new Student("liushishi", 22);Student s3 = new Student("fengqingy", 23) ;Student s4 = new Student("wuqilong", 35) ;Student s5 = new Student("gaoyuanyuan",27) ;Student s6 = new Student("zhangguorong",29) ;Student s7 = new Student("gaoyuanyuan",26) ;//添加元素ts.add(s1) ;ts.add(s2) ;ts.add(s3) ;ts.add(s4) ;ts.add(s5) ;ts.add(s6) ;ts.add(s7) ;//增强for遍历for(Student s : ts){System.out.println(s.getName()+"----"+s.getAge());}}}

7

 Collection集合中关于:toString()方法的源码

  如果在一个类中没有找到该方法,继续往它的父类中找;

import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public String toString() {        Iterator<E> it = iterator();//this.iterator() ;        if (! it.hasNext())    //首先判断迭代器是否由下一个可以跌倒的元素            return "[]";//迭代器中有可以遍历元素        StringBuilder sb = new StringBuilder();//创建了一个字符串缓冲区        sb.append('[');        for (;;) {            E e = it.next(); //获取元素            sb.append(e == this ? "(this Collection)" : e);            if (! it.hasNext())//最终如果集合中没有可以迭代(遍历)的元素                return sb.append(']').toString();//拼接右中括号,转换String类型            sb.append(',').append(' '); //中间每一个元素拼接逗号和空格        }    }public class CollectionDemo {public static void main(String[] args) {//创建Collection集合对象:Collection<String> c = new ArrayList<String>() ;=//添加元素c.add("hello") ;c.add("world") ;c.add("Java") ;System.out.println(c);}}//    [hello, world, Java]

8 Random

import java.util.Random;

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

构造方式:

public Random()创建一个新的随机数生成器:默认种子不给定long类型的时间毫秒值

成员方法:

public int nextInt():由随机数生成器调用这个方法,随机数的范围在int类型的范围之内

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


import java.util.Random;public class RandomDemo {public static void main(String[] args) {//创建一个随机数生成器Random r = new Random();for(int x = 0 ; x <10 ; x ++){//随机数生成器:r调用他们的成员方法//int number = r.nextInt() ;//public int nextInt(int n):生成随机数的范围:[0,n)int number = r.nextInt(20) +1;System.out.println(number);}}}

综合案例

用户登陆注册案例:

符号面向对象分析特点:

1)当前需求中有哪些类?

2)知道某些类,这些类中有什么东西

3)这些类和类之间有什么关系

1)有哪些类:

用户类

用户的基本信息描述:

在这个基本描述类中提供:成员:username password ,提供set()/get()方法

具体的划分:

按照功能划分:

         注册功能

         登陆功能

用户操作的接口:

         注册();登陆();

用户操作的接口实现类:

          注册(){..}

          登陆(){..}

用户要进行操作:

         注册

         登陆

测试类:

         Usertest:用户测试类:

         用户类和测试类:

         在测试类中需要创建用户类对象,来操作登陆和注册功能

经常会按照功能划分,模块划分:

         1)先按照功能划分,在按照模块划分

         2)先模块划分,功能划分.                         

给每一个包命名的时候:

         用户的描述类:user类

         包:公司域名.entity;实体类

                            org.westos.entity;

         用户操作的接口:

                   包:公司域名.dao:里面放的是接口

                      org.westos.dao :接口层

         用户操作接口的实现类:

                   包:

                            org.westos.dao.impl:业务逻辑层:接口子实现类

         测试类:

                   包:

                            org.westos.test:需要针对注册或者的登陆进行测试

                           

1  //用户的实体类

public class User {         //成员变量         privateString username;         privateString password;         publicUser() {                   super();         }         publicString getUsername() {                   returnusername;         }         publicvoid setUsername(String username) {                   this.username= username;         }         publicString getPassword() {                   returnpassword;         }import org.wesots.entity.User; // 用户的操作接口public interface UserDao {                 /**           该方法是用户登陆功能           @param username           被传递的用户名           @param password           需要被传递的用户密码           @return           返回值表示最终登陆是否成功          */         publicabstract boolean isLogin(String username,String password) ;         /**          该方法表示是用户注册功能          @param user         表示需要注册的用户          */         publicabstract void regist(User user) ;}         publicvoid setPassword(String password) {                   this.password= password;         }} /**

/**

 这是用户操作的接口实现类:业务逻辑层

 集合版

 */

import java.util.ArrayList;import org.wesots.entity.User;import org.westos.dao.UserDao;public class UserDaoImpl implements UserDao {//为了多个功能使用这个集合中的用户,将集合的对象定义到成员变量中//为了不让外界修改集合,所以private修饰//将集合对象共享:注册和登陆使用的同一个集合对象private static ArrayList<User> array = new ArrayList<User>() ;//登陆功能public boolean isLogin(String username, String password) {//登陆,需要将注册的时候用户全都遍历出来,所以创建ArrayList集合//假设:定义标记,用户登陆不成成功boolean flag = false ;//需要遍历集合获取集合中的每一个用户for(User u :array){//获取到每一个用户对象:u//判断if(u.getUsername().equals(username) && u.getPassword().equals(password)){//修改标记flag = true ;break ;}}return flag ;}//注册功能public void regist(User user) {//由于有很多用户,需要将用户存储到集合中,需要创建一个集合//ArrayList<User> array = new ArrayList<User>() ;//将用户存储到集合中array.add(user) ;}}//猜数字游戏的类import java.util.Scanner;public class GuessNumberGame {// 无参构造私有private GuessNumberGame() {}//静态功能public static void start(){//产生一个随机数int number = (int) (Math.random()*100 +1) ;//定义一个统计变量int count = 0 ;//多次循环while(true){//创建键盘录入对象Scanner sc = new Scanner(System.in) ;System.out.println("请你输入一个数据:");int guessNumber = sc.nextInt() ;//统计变量++count ++ ;if(guessNumber>number){System.out.println("你要猜的数据"+guessNumber+"大了");}else if(guessNumber <number){System.out.println("你要猜的数据"+guessNumber+"小了");}else{System.out.println("恭喜您"+count+"次猜中了");break ;}}}}

用户的测试类

 注意事项:

1)登陆功能和注册功能使用的是同一个集合,将集合的对象的数据共享,应该用static

   2):登陆成功应该退出界面,

现在使用switch语句,遇见break,只是结束switch语句并不能结束循环语句----->

public class UserTest {public static void main(String[] args) {//为了能够回来,加入while循环while(true){//给出选择的界面System.out.println("-------------------欢迎光临------------------------");System.out.println("请选择:");System.out.println("1  登陆");System.out.println("2  注册");System.out.println("3  退出");//创建键盘录入对象Scanner sc = new Scanner(System.in) ;//根据不同的选择给出界面,简单分析下//为了方便数据的录入,就是用String类型接收String choiceString = sc.nextLine() ;//由于用户都需要调用登陆和注册功能,通过接口多态,所以将该用户操作的登陆对象定义到switch语句外面UserDao ud  = new UserDaoImpl() ;//简单分析:就可以使用switch语句switch(choiceString){case "1"://登陆界面System.out.println("------------登陆界面--------------");System.out.println("请输入用户名:");String username = sc.nextLine() ;System.out.println("请您输入密码:");String password = sc.nextLine() ;//需要调用登陆功能//UserDao ud = new UserDaoImpl() ;boolean flag = ud.isLogin(username, password) ;//判断if(flag){System.out.println("登陆成功,开始玩游戏吗?");System.out.println("玩游戏吗?y/n");while(true){String resultString = sc.nextLine();if(resultString.equalsIgnoreCase("y")){//开始玩游戏GuessNumberGame.start() ;System.out.println("你还玩吗?y/n");}else{break ;}}System.out.println("谢谢使用,下次再来...");//break ;//遇见break,只是结束switch语句并不能结束循环语句System.exit(0) ;}else{System.out.println("用户名或者密码错误,请重新输入....");}break ;case "2"://注册界面System.out.println("------------注册界面--------------");System.out.println("请您输入用户名:");String newUserName = sc.nextLine() ;System.out.println("请您输入密码:");String newPassword = sc.nextLine() ;//将用户名和密码封装到用户对象中User u = new User() ;u.setUsername(newUserName) ;u.setPassword(newPassword) ;//调用注册的功能://接口多态://UserDao ud = new UserDaoImpl() ;ud.regist(u) ;System.out.println("注册成功..");break ;case "3":default:System.out.println("谢谢使用,下次再来!");System.exit(0) ;break ;}}}