1、利用集合来实现注册、登录等功能。
包的命名:
实体类:org.westos.entity 实体类:User
数据访问对象dao:org.westos.dao 注册、登录功能
接口实现类:org.westos.dao.Impl
测试类:org.westos.test
2、Set集合和List集合的区别?
Set集合:不允许元素重复,唯一的(元素可以为null) ,不能保证迭代的顺序恒久不变(底层哈希表和hascode)、无序(存储和取出不一致)
List:允许元素重复,并且存储特点:有序性(存储和取出一致)
Set存储元素时的唯一性:
HashSet集合的add方法底层依赖于双列集合HashMap,它依赖于两个方法,HashCode()方法和 equals()方法;先比较字符串的HashCode()码值一样,再比较equals()方法;如果hashCode码值一样,还要比较内容是否相同,由于存储String,String本身重写了equals()方法。但是在存储自定义对象时, 在Student类中并没重写这两个方法,解决,重写这两个方法,因此需要我们重写这两个方法。
Set.add()的原码分析:
class HashSet implements Set{
private HashMap<E,Object> map;
//创建HashSet集合对象的时候,起始底层创建了一个HashMap集合对象
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null; //add方法底层依赖于HashMap集合的
}
}
class HashMap<K,V> implements Map<K,V>{
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
//putVal方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i; //Node是一种键值对对象
//判断哈希表示是为空,如果为空.有set集合元素的情况,哈希表不为空
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k; //k--->传入的元素
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
//一些判断,主要还是eqauls()方法
e = p; /e =p = key
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key mapping:映射 (Servlet servlet-mapping)
V oldValue = e.value; //e.value=key ="hello" ,"world","java","world","java"
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue; //返回的oldValue:永远是第一次存储的哪个元素
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
}
哈希方法
static final int hash(Object key) { //传入的字符串元素 "hello","java","world" ,"hello"....
int h; //哈希码值
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); //无符号右移
底层依赖于第一个方法hashCode() 计算机底层运算数据:补码
}
Set<String> set = new HashSet<String>() ;
set.add("hello") ;
set.add("java") ;
set.add("world");
set.add("hello") ;
set.add("java") ;
set.add("world");
3、如果在开发中,元素唯一性,并且还要保证元素有序(存储和取出一致),使用LinkedHashSet集合
LinkedHashSet集合:
底层是一种链接列表和哈希表组成
可以保证元素的唯一性,是由哈希表决定的(hashCode()和equals())
可以保证元素的迭代顺序一致(有序),存储和取出一致,是由链表决定
4、TreeSet集合模拟情况下是通过自然顺序对集合中的元素排序
TreeSet:
可以保证元素唯一并且元素排序(Integer类型的元素自然升序)
自然排序
比较器排序
(1)自然排序
在treeSet存储自定义对象时,例如Student他不知道如何排序,所以自定义的类型必须实现Comparable,实现接口中的方法compareTo() :比较方法,重写方法
代码如下:
public int compareTo(Student s) { //源码 cmp = k.compareTo(t.key),分析源码
//return 0;
//按照某种规则,前提必须有这规则
//主要条件:按照年龄从小到大
int num = this.age - s.age ; //如果年龄相等,不一定是同一个人
//需要自己分析次要条件;
//年龄相同,姓名的内容不一定相同,比较姓名
int num2 = num==0 ? this.name.compareTo(s.getName()) : num ;
return num2 ;
}
(2)比较器排序
Comparator保证集合中的元素进行比较器排序
(3)TreeSet集合的构造方式不同,使用的排序也不同
自然排序:自定义的类实现Compareable接口,然后创建TreeSet对象,通过无参构造形式创建对象
比较器排序 :public TreeSet(Comparator<E> comparator)
两种方式:
(1)自定义一个类,该类实现Comparator接口,重写Comparator接口中的compare()方法
(2)直接使用接口匿名内部类的方式实现
TreeSet集合保证元素唯一,是看返回值是否为0
保证元素进行排序,两种排序方式
使用比较器排序的方式去,遍历Student对象,并且按照姓名长度进行比较
5、Map集合:键值的映射关系的一种集合(接口)
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map<K,V> ,在Map集合中,只针对键有效,跟值无关 Map接口的子实现类:HashMap和TreeMap
面试题:
Map集合和Collection的区别?
Map集合:是一种键和值的映射关系(双列集合) 当作为:夫妻对
Collection集合:单列集合,只能存储一种类型的元素,当作为:光棍
间接关系:HashSet依赖于Map接口的子实现类HashMap的
TreeSet依赖于Map接口的子实现类TreeMap的
Map接口的功能:
V put(K key,V value) :添加功能:将指定的值和键关联起来
如果当前的这个键是一次存储,则返回值null
如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉!
获取功能
Set<Map.Entry<K,V>> entrySet() :和Map集合的遍历有关系(键值对对象)
Set<K> keySet():获取映射关系中所有的键的集合
int size()返回此映射中的键-值映射关系数
删除功能
void clear():删除所有映射关系
Vremove(Object key)如果存在一个键的映射关系,则将其从此映射中移除
判断功能:
boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true
boolean containsValue(Object value):映射关系中是否包含指定的值
boolean isEmpty():判断映射关系是否为空
Map的两种遍历:
(1)这种遍历方式实际开发中经常用的...
Set<K> keySet():获取映射关系中所有的键的集合
V get(Object key):通过键找值
转换法:
1)将所有的丈夫集中起来
2)让丈夫它对应的妻子
3)将他们遍历出来
(2)Map集合的另一种方式的遍历 Set<Map.Entry<K,V>> entrySet() :和Map集合的遍历有关系(键值对对象)
转化法: 1)获取所有的结婚证 2)通过结婚证分别找对应的丈夫和妻子 3)遍历输出
思路: 1)获取所有的键值对象entrySet()
2) K getKey() 和 v getValue(),获取键值对对象中的每个键和每个值
3)遍历