一、Set映射
1、Set接口
比方说1:N的关系,一个对象对应多个对象,这些对象怎么保存?需要使用集合保存这些对象。一个分类对应多个很多的商品。
2、三者之间的区别
(1)HashSet
HashSet有以下特点
l 不能保证元素的排列顺序,顺序有可能发生变化
l 不是同步的
l 集合元素可以是null,但只能放入一个null
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。
(2)LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。
(3)TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
l 自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是 负数,则表明obj1小于obj2。
如果我们将两个对象的equals方法总是返回true,则这两个对象的compareTo方法返回应该返回0
l 定制排序
自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法。
3、实例
(1)初始化数据库。(建表)
(2)生成持久化类(User类),并在该类中添加属性emails用来保存该对象的所有Email列的值。并添加Getter和Setter方法。
import java.util.HashSet;
import java.util.Set;
public class User implements java.io.Serializable {
private static final long serialVersionUID = 3855149643658782259L;
private Integer id;
private String username;
private String password;
//用集合表示这个人的所有Email
private Set emails = new HashSet();
public User() {
}
//设置Set和get方法
public Set getEmails() {
return emails;
}
public void setEmails(Set emails) {
this.emails = emails;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
(3)修改User.hbm.xml文件,如下:
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
该文件的说明:
另外由于User表在SQL Server中不能用,所以给它加上中括号。
(4)测试文件,如下:
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.pojo.User;
importcom.utils.HibernateSessionFactoryUtil;
public class gbTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
get();
}
public static void get(){
Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
User u = (User) session.load(User.class, new Integer(3));
System.out.println(u.getUsername());
System.out.println(u.getPassword());
Set set = u.getEmails();
for(Object o:set){
System.out.println(o);
}
//这一句一定要放在处理完毕,否则会报错
tx.commit();
}
public static void add(){
Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
User u = new User();
u.setUsername("bjl");
u.setPassword("8888");
u.getEmails().add("bjl@sina.com");
u.getEmails().add("bianjilaig@163.com");
Transaction tx = session.beginTransaction();
session.save(u);
tx.commit();
}
}
二、List接口
1、两者之间的区别
ArrayList和LinkedList的大致区别:
l ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
l 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
l 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
2、性能比较
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
l 对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
l 在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
l LinkedList不支持高效的随机元素访问。
l ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
3、实例(1:04)
将上面的例子使用List来实现。
(1) 修改表的结构(因为List要记录插入的顺序),增加idx字段(整数)
(2) 将上述的user.java中的emails类型修改为List。代码如下:
private List emails = new ArrayList();
public User() {
}
//设置Set和get方法
public List getEmails() {
return emails;
}
public void setEmails(List emails) {
this.emails = emails;
}
(3) 修改User.hbm.xml映射文件,代码如下:
(4) 修改测试类,将所有的Set类型的修改为List类型
(5) 程序运行以后,数据库中的结果如下:
PS:在今后的应用当中,经常用的是Set,List不会常用,原因是记录顺序意义不大。