黑马程序员_集合-set实现类

来源:互联网 发布:自学php能找到工作吗 编辑:程序博客网 时间:2024/05/22 13:56
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------



面试题:用集合改进登陆注册案例
关于登陆注册的案例,我们在第14天的教程中,已经学习过了。
本次用集合改进“登陆注册”,仅仅是把包 cn.itcast.dao.impl
中的 类UserDaoImpl 中的内容给修改了下。


public class UserDaoImpl implements UserDao {
//创建集合对象
private static ArrayList<User> array = new ArrayList<User>();

@Override
public boolean isLogin(String username, String password) {
// 遍历数组,获取到每一个对象,
// 然后再拿对象的用户名和密码和传递过来的用户名和密码进行比较
boolean flag = false;
//遍历集合,获取每一个用户,如果存在,就修改标记为true
for(User u : array)
{
if(u.getUsername().equals(username) && u.getPassword().equals(password))
{
flag = true;
break;
}
}
return flag;
}


@Override
public void regist(User user) {
//将该用户添加到集合中
array.add(user);
}


}






1:Set(掌握)
(1)Set的特点:
元素无序,唯一。(注意和List的对比:元素有序(数据存储和取出顺序一致),可以重复。)
注意:这里的顺序是指存储和取出顺序。


2:HashSet(掌握)
(1)HashSet:不保证元素的迭代顺序。并且,不保证该顺序恒久不变。
(2)怎么保证的呢?
HashSet底层数据结构是哈希表。
它依赖两个方法:hashCode()和equals()
顺序:
首先,判断hashCode()值是否相同。
相同:
继续走equals()方法,根据其返回值:
true:说明元素重复,不添加到集合。
false:说明元素不重复,添加到集合。
不同:直接添加到集合。


(3)怎么重写hashCode()和equals()方法呢?(忘了吧)
hashCode():
把对象的所有成员变量值相加即可。
如果是基本类型,就加值。如果是引用类型,就加哈希值。
public int hashCode()
{
return this.name.hashCode() + this.age + this.sex +this.score ;
}
equals():
A:this==obj
B:!(obj instanceof Student)
C:所有成员变量的值比较。基本类型用==,引用类型用equals()。


如果不会,eclipse()自动生成。





3:TreeSet(理解)
(1)TreeSet:根据构造方法的不用,选择使用自然排序或者比较器排序。
           按照实际的需求,可以对元素进行排序。并且保证唯一。
(2)怎么保证的呢?
排序:底层结构是二叉树。按照树节点进行存储和取出。
两种实现:
A:自然排序(元素具备比较性)


TreeSet的无参构造,要求对象所属的类实现Comparable接口。
public int compareTo( Studetn s )
{
//需求是比较年龄
int num = this.age - s.age ;
//由于对象有多个成员变量,你不能根据其中的某一个决定其他的。
//当某一个形同的时候,你还需要判断其他的是不是也是相同的。
int num2 = ( num == 0 ) ? ( this.name.compareTo( s.name ) ) : num ;
return num2;
}


B:比较器排序(集合具备比较性)


TreeSet的带参构造,要求构造方法接收一个实现了Comparator接口的对象。


TreeSet<Student> ts = new TreeSet<Student> ( new Comparator<Student> 
{
@Override
public int compare ( Student s1 , Student s2)
{
//按照年龄排序,从小到大
int num = s1.getAge() - s2.getAge();
//次要条件
int num2 = ( num == 0 ) ? ( s1.getName().compareTo(s2.getName()) ) : num;
return num2;
}
} );


//创建元素对象
Student s1 = new Student(“张三”,24);
Student s2 = new Student(“李四”,30);
Student s1 = new 。。。。。。
//添加元素
ts.add(s1);
ts.add(s2);
...........
for( Student s : ts )
{
System.out.println(s.getName() + "*****" + s.getAge());
}




唯一:根据返回值是否为0。

注意:
如果同时有两种方案,以谁为主呢?以比较器为主。

(3)案例:TreeSet存储自定义对象按照姓名长度排序
public int compareTo( Studetn s )
{
//需求是比较姓名的长度
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 ) : num3 ; 
return num3;
}


(4)原理:二叉树保证元素唯一 排序
A:第一个添加的数据作为根节点。
B:从第二个开始,
每一个数据从根节点开始比较,
如果大了,往右边放,
如果小了,往左边放,
如果相同,替换。
C:从根节点开始,获取数据的规则,是按照每个数据的:左,中,右原则。




4:Collection体现的集合总结
Collection
|--List
|--ArrayList
底层数据结构是数组,查询快,增删慢
线程不安全,效率高。
|--LinkedList
底层数据结构是链表,查询慢,增删快
线程不安全,效率高。
|--Vector
底层数据结构是数组,查询快,增删慢
线程安全,效率低。
|--Set 唯一
|--HashSet
底层数据结构是哈希表。
如何保证元素唯一性呢?
依赖两个方法。hashCode()和equals()。
以后都自动生成。
|--TreeSet
底层数据结构是二叉树。
如何保证元素唯一性呢?如何保证元素排序呢?
根据返回值是否是0,判断元素是否重复。
排序有两种方案:
元素具备比较性 实现Comparable接口
集合具备比较性 实现Comparator接口


5:在集合中的数据结构问题
ArrayXxx:底层数据结构是数组。查询快,增删慢。
LinkedXxx:底层数据结构是链表。查询慢,增删快。
HashXxx:底层数据结构是哈希表。跟两个有关。hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种排序方式。Comparable接口和Comparator接口


6:什么时候,使用哪种Collection集合。
元素唯一吗?
唯一:
Set
需要排序吗?
需要:TreeSet
不需要:HashSet


不知道,用HashSet。
不唯一:
List
需要安全码?
需要:Vector
不需要:ArrayList和LinkedList
查询多:ArrayList
增删多;LinkedList
不知道,用ArrayList。


7:Collections(理解)
(1)Collections是针对Collection集合操作的工具类。


public static void sort ( List list ):排序。
public static <T> int binarySearch( List list, T key ):二分查找。
public static void reverse( List list ):反转。
public static T max( Collection coll ):最大值。
public static void shuffle( List list ):随机置换 (相当于“洗牌”)


(2)面试题:


Collection和Collections的区别?
Collection:是Collection集合的顶层接口,定义了Collection集合的共性方法。
Collections:是一个类,定义了针对Collection集合操作的功能,有排序,查找,反转等。


(3)案例:斗地主洗牌发牌小游戏
public static void main(String[] args) {
// 买牌
// 表示花色的数组
String[] colors = { "黑桃", "红桃", "梅花", "方块" };
// 表示点数的数组
String[] numbers = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"J", "Q", "K" };


// 早一个牌盒
ArrayList<String> array = new ArrayList<String>();
array.add("大王");
array.add("小王");


// 循环装牌
for (String c : colors) {
for (String n : numbers) {
array.add(c.concat(n));
}
}
// 显示所有牌
// System.out.println(array);


// 洗牌
Collections.shuffle(array);
// 显示所有牌
// System.out.println(array);


// 发牌
ArrayList<String> linString = new ArrayList<String>();
ArrayList<String> zhouString = new ArrayList<String>();
ArrayList<String> meString = new ArrayList<String>();


// 用普通for
for (int x = 0; x < array.size() - 3; x++) {
if (x % 3 == 0) {
linString.add(array.get(x));
} else if (x % 3 == 1) {
zhouString.add(array.get(x));
} else if (x % 3 == 2) {
meString.add(array.get(x));
}
}


// 看牌
System.out.println("linString:" + linString);
System.out.println("zhouString:" + zhouString);
System.out.println("meString:" + meString);


// 看底牌
for (int x = array.size() - 3; x < array.size(); x++) {
System.out.print(array.get(x) + "  ");
}
}









------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
0 0
原创粉丝点击