您的位置:首页 > 职场人生

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

2015-08-22 18:55 513 查看
------- <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>、期待与您交流! ----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: