Set集合
1.Set接口:Set集合继承自Collection集合
Set:底层数据结构是一个哈希表,能保证元素是唯一的,元素不重复!
它通过它的子实现了HashSet集合去实例化,HashSet集合底层是HashMap集合的实例
2.演示:Set集合存储字符串元素并遍历
public 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);
}
}
}
HashSet集合
1.Set集合的子实现类:
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;
特别是它不保证该顺序恒久不变.
2.看源码
HashSet集合的add()方法,底层是依赖于双列集合HashMap
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);
}
}
}
4.HashSet集合的add()方法的源码:
interface Collection{}
interface Set Extends Collection{
}
class HashSet<E> implements Set<E>{
private transient HashMap<E,Object> map;
//HashSet集合的无参构造方法
public HashSet() {
map = new HashMap<>();
}
//HashSet集合的添加功能:
public boolean add(E e) {//"hello","world","world"
return map.put(e, PRESENT)==null;//"hello","world","world"= e
}
}
class HashMap<K,V> implements Map<K,V>{
//HashMap集合添加元素的功能
public V put(K key, V value) {//k="hello","world"
if (table == EMPTY_TABLE) {//table:判断哈希表示==空表
inflateTable(threshold);
}
if (key == null)//元素是空
return putForNullKey(value);
int hash = hash(key);//携带当前HashSet集合中的元素:"hello","world","world" :第一次的world和第二次world返回到HashCode值一样
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {//for循环:遍历键值对象的(Map集合遍历)
Object k;
if (ase.hh == hash && ((k = e.key) == key || key.equals(k))) {
//e:每一个元素:要判断他们的hashCode值是否一样,如果hashCode值一样还要判断他们的equals()方法,而对于String类型来说,底层已经重写了
Object中的equals()方法,所以比较多是内容是否相同
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue; //hashCode()值一样,在比较内容是否相同,(如果相同),直接返回第一次存储的"world"
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
//hash()方法
final int hash(Object k) {"hello","world","world
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();//每一个元素都要调用:hashCode();是Object类中的方法
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
}
//创建HashSet集合对象
HashSet<String> hs = new HashSet<String>();
//给该集合中添加元素
hs.add("hello") ;
hs.add("world") ;
hs.add("world") ;
hs.add("Java") ;
hs.add("Java") ;
5.List集合和Set集合的区别?
Set:元素是唯一的,无序性(存储和取出不一致)
List:元素可以重复,有序性(存储和取出一致)
由于现在是自定义对象:在当前自定义对象的类中没有重写两个方法
hashCode和equals()方法;HashSet底层是依赖于这两个实现来保证元素的唯一性
6.演示:使用HashSet集合存储自定义对象并遍历
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
//创建一个HashSet集合对象
HashSet<Student> hs = new HashSet<Student>() ;
//创建学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("张三", 25) ;
Student s3 = new Student("唐嫣", 26) ;
Student s4 = new Student("邓超", 29) ;
Student s5 = new Student("胡歌", 23) ;
Student s6 = new Student("高圆圆", 27) ;
//给集合中添加学生对象
hs.add(s1) ;
hs.add(s2) ;
hs.add(s3) ;
hs.add(s4) ;
hs.add(s5) ;
hs.add(s6) ;
//增强for遍历
for(Student s : hs){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
6.Set集合的子实现类:
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;
特别是它不保证该顺序恒久不变。
看源码:
HashSet集合的add()方法,底层是依赖于双列集合HashMap
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);
}
}
}
//学生类
public class Student {
private String name ;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
//自动生成
@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;
Student other = (Student) 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;
}
}
LinkedHashSet集合
1.具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。
2.LinkedHashSet集合:
由哈希表保证元素的唯一性
由链接列表来保证元素的有序性!
3.演示:
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);
}
}
}
TreeSet集合
1.TreeSet:Set集合中的一个重点
TreeSet集合底层是依赖于TreeMap的实例,而TreeMap
/**
* TreeSet存储Integer类型添加以下元素
* 20,18,23,22,17,24,19,18,24
*/
import java.util.TreeSet;
public 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,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遍历
for(Integer i : ts){
System.out.print(i+ " ");//17 18 19 20 22 23 24 :唯一并且排序:自然排序(升序排序)
}
}
}
3.TreeSet集合存储自定义对象并遍历
实现了compareable接口,重写了comapreTo()方法,里面的逻辑是一个排序条件:
4.一个类中的元素想要自然排序,那么必须实现Compareable接口,实现compareTo(类名 对象名){}方法
5.按照正常存储对象的操作以及遍历对象出现了问题:
类转换异常
java.lang.ClassCastException: org.westos_04.Student cannot be cast to java.lang.Comparable
6.演示:
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());
}
}
}
package org.westos_04;
//对于TreeSet集合存储自定义对象必须实现一个接口:compareable接口
public class Student implements Comparable<Student>{
private String name ;
private int age ;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
//重写了compareTo()方法
@Override
public int compareTo(Student s) {
// return 0;
//排序的代码了,需要定义排序的条件
//主要条件:按照学生的年龄从小到大进行排序
int num =s.age - this.age ;//年龄从大到小
// return num ;
//当num==0认为年龄一样,年龄一样,不代表姓名的的内容是否相同,需要自己给出次要条件
int num2 = num==0 ? this.name.compareTo(s.name): num ;
return num2 ;
}
}
9.TreeSet集合的add()方法的源码:
interface Collection{
}
interface Set extends Collection{
}
class TreeSet implements Set{
private transient NavigableMap<E,Object> m;
//无参构造方法
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
}
class TreeMap<K,V> implements NavigableMap<K,V>{
private transient int modCount = 0; 该变量不会被序列化
//Map集合中添加元素的方法
public V put(K key, V value) {///20,18,23,22,17,24,19,18,24 = key
Entry<K,V> t = root;//root=第一次存储的20这个元素
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;//父节点==t==20
// split comparator and comparable paths
//比较器排序
Comparator<? super K> cpr = comparator;//this.comparaptr;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);//t.key==通过根节点和后面依次传来的元素进行比较
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);//键值对象不能为null
}
else {
//自然排序:由于创建TreeSet集合对象TreeSet():无参构造形式
if (key == null)//key=需要存储的元素://20,18,23,22,17,24,19,18,24--->Integer类型
throw new NullPointerException();//一定空指针异常
Comparable<? super K> k = (Comparable<? super K>) key; //声明了一个接口对象:Comparable接口对象 :this.key
do {
parent = t;//20
cmp = k.compareTo(t.key);t.key==通过根节点和后面依次传来的元素进行比较
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
//存储元素
Entry<K,V> e = new Entry<>(key, value, parent); //创建新的键值对象
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++; //将元素分别依次取出来
return null;
}
}
结论:对于TreeSet集合要实现自然排序,那么该集合该集合中存储自定义类型必须实现一个接口:Comparable,并且重写该接口中的compareTo()方法
使用TreeSet集合存储自定义对象并遍历
10.演示:
import java.util.TreeSet;
/**
* 需求:按照学生姓名长度从小到大进行排序
* @author Apple
*/
public class TreeSetTest {
public static void main(String[] args) {
//创建TreeSet集合对象
TreeSet<Student> ts = new TreeSet<Student>() ;
//创建几个学生对象
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(Student s : ts){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
//如果一个类中的元素要实现自然排序,就必须实现Compareable接口
public class Student implements Comparable<Student> {
private String name ;
private int age ;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
//元素唯一性:取决返回值是否为0
@Override
public int compareTo(Student s) {
// return 0;
//主要条件按照学生姓名长度从小到大进行排序
int num = this.name.length() - s.name.length() ;
//次要条件:
//姓名长度一样,能代表姓名的内容一样吗?
//在增加一个条件:姓名长度一样,还需需要比较内容是否一样
int num2 = num==0?this.name.compareTo(s.name) :num ;
//次要条件:姓名长度一样,内容也一样,不一定年龄一样,所以还需要比较年龄是否相同;
int num3 = num2==0? this.age - s.age : num2 ;
return num3 ;
}
}
11.演示:
import java.util.Comparator;
import java.util.TreeSet;
/**
* 需求:按照学生姓名长度从小到大进行排序
*
* //元素唯一性:取决返回值是否为0
* 要使用TreeSet集合的比较器排序:
* 依赖于构造方法:
* public TreeSet(Comparator<E> comparator)
*
* 两种方式实现比较器排序:
* Comparator接口作为形式参数进行传递,需要该接口的子实现类对象
*/
public 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>() {
@Override
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());
}
}
}
package org.westos_06;
public class Student {
private String name ;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
}
import java.util.Comparator;
//MyComparatpr是Comparator接口的子实现类
public class MyComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
// return 0;
// 按照学生姓名长度从小到大进行排序
//int num = this.name.lengt()-s.name.length();
//this--:s1
//s---: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 ;
}
}
12.演示:
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
*
* 分析:
* 1)创建一个学生类,提供姓名,语文,数学,英语这个成员变量
* 2)创建TreeSet集合对象:TreeSet<Student>(Comparator<Student> com)
* 3)分析条件:主要条件:总分从高到低
* 次要条件:总分相同,语文..
* 4)键盘录入5个学生:for循环
* 5)输出
* @author Apple
*/
public class TreeSetTest {
public static void main(String[] args) {
// 创建TreeSet集合对象,使用有参构造
// 比较器排序匿名内部类的方式
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<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("录入学生信息开始:");
// 键盘录入5个学生的信息,姓名,语文成绩,数学成绩,英语成绩
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());
}
}
}
public class Student {
private String name ;//姓名
private int chinese ;//语文
private int math ;//数学
private int english;//英语
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int chinese, int math, int english) {
super();
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
//总分的方法
public int getSum(){
return this.chinese + this.math+this.english ;
}
}
13.Collection集合中关于:toString()方法的源码
如果在一个类中没有找到该方法,继续往它的父类中找
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(' '); //中间每一个元素拼接逗号和空格
}
}
[hello, world, Java]
14.演示:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
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);
}
}
使用集合来模拟用户登陆注册
1.Random:产生一个随机数的类:
2.构造方式:
public Random()创建一个新的随机数生成器:默认种子不给定long类型的时间毫秒值
3.成员方法:
public int nextInt():由随机数生成器调用这个方法,随机数的范围在int类型的范围之内
public int nextInt(int n):生成随机数的范围:[0,n):使用比较多
4.演示:
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);
}
}
}
5.演示:
package org.westos_random;
import java.util.ArrayList;
import java.util.Random;
/**
* 获取10个1-20之间的随机数,要求不能重复
*
* 数组来操作,数组弊端,长度固定,使用集合存储
*
* 分析
* 1)创建一个随机数生成器:Random类来创建
* 2)使用ArrayList集合去存储,数据类型:Integer
* 3)定义中统计变量count,
* 4)循环判断如果统计变量小于10
* 通过随机数生成器获取1-20之间的数据
* 判断集合中是否包含这些随机数,如果不包含,猜添加到集合中
* count ++
* 5)遍历集合,拿到元素
* @author Apple
*/
public class Test {
public static void main(String[] args) {
//1)创建一个随机数生成器
Random r = new Random();
//2)创建ArrayList集合,类型Integer
ArrayList<Integer> array = new ArrayList<Integer>() ;
//3)定义统计遍历
int count = 0 ;
//4)循环判断
while(count <10){
//通过随机数生成器获取:1-20之间的随机数
int number = r.nextInt(20) +1;
//有随机数了,还需要判断集合中是否包含这些随机数
if(!array.contains(number)){
//如果不包含,才添加到集合中
array.add(number) ;
count ++ ;
}
}
//遍历集合:增强for
for(Integer i : array){
System.out.println(i);
}
}
}
标题
1.
如何分析需求:
用户登陆注册案例:
符号面向对象分析特点:
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:需要针对注册或者的登陆进行测试
2.用户的实体类
package org.wesots.entity;
public class User {
//成员变量
private String username;
private String password;
public User() {
super();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
3.用户的操作接口
import org.wesots.entity.User;
public interface UserDao {
/**
* 该方法是用户登陆功能
* @param username
* 被传递的用户名
* @param password
* 需要被传递的用户密码
* @return
* 返回值表示最终登陆是否成功
*/
public abstract boolean isLogin(String username,String password) ;
/**
* 该方法表示是用户注册功能
* @param user
* 表示需要注册的用户
*/
public abstract void regist(User user) ;
}
4.用户操作的接口实现类:业务逻辑层(集合版)
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>() ;
//登陆功能
@Override
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 ;
}
//注册功能
@Override
public void regist(User user) {
//由于有很多用户,需要将用户存储到集合中,需要创建一个集合
// ArrayList<User> array = new ArrayList<User>() ;
//将用户存储到集合中
array.add(user) ;
}
}
5.用户的测试类
import java.util.Scanner;
import org.wesots.entity.User;
import org.westos.dao.UserDao;
import org.westos.dao.impl.UserDaoImpl;
import org.westos.game.GuessNumberGame;
/**
* 注意事项:
* 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 ;
}
}
}
}
6.猜数字游戏的类
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 ;
}
}
}
}