首先我们先初步知道下Set与List的区别?
Set 集:不区分元素的顺序,不允许出现重复元素
List 列表:区分元素的顺序,且允许包含重复元素
List接口 List<E>泛型
List容器中的元素都对应一个整数型的序号记 载其在容器中的位置,可以根据序号存取容器中的元素。
List接口中有add,set,indexOf方法,但是Set接口中只有add方法,没有set,indexOf方法,因为Set是无序不能重复的,不存在某元素具体位置这个概念。
List介绍:
ArrayList和LinkedList都实现了List接口中的方法,但两者内部实现不同
ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表完成,其内每个对象出来数据本身外,还有两个引用,分别指向前一个元素和后一个元素。
ArrayList 存取速度快,插入删除慢
LinkedList 存取速度慢,插入删除速度快 List it=new LinkedList
记住:LinkedList中是没有shuffle方法,因此需要Collections类的相关方法来实现。如有需要则Collections.shuffle(it);
倒置:Collection.reverse(it);
排序:Collections.sort(it);
但是这里咋们要知道
Colletions 是类
Colletion 是接口
Collection接口的实现类,如ArrayList,LinkedList本身并没有提供排序,倒置,查找等方法,这些方法是由Colletions类来实现的,该类有很多public static方法,可以直接对Colletion接口类进行操作
eg:(java.util.Collections )
sort(List)正常排序 。shuffle(List) 随机排序。
reverse(List) 逆序排序 。
fill(List,object) 用一个特定的对象重写整个List容器
copy(List dest,List src) 将src List容器内容拷贝到dest List容器
int binarySearch(List,object)对于顺序的List容器,采用折半查找特定对象
强烈建议:所有添加到Collection容器中的对象都应该重写父类Object的toString方法。如果没有toString,程序输出会出现乱码
import java.util.*;
public class TestCollection{
public static void main(String[] arg){
Collection c=new LinkedList();
c.add(new Student("zhangsan",80));
c.add(66.6);
System.out.println(c);
}
}
class student{
private String name;
private int age;
public student(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return name+""+age;
}
}
其中还有一个
Comparable接口
//如果希望把对象放到List当中,必须要有一个比较标准,实现接口Comparable以及comparaTo方法
//做过比较才能用Collections.()
class Student implements Comparable{
private String name;
private int id;
public Student(String name,int id){
this.name=name;
this.id=id;
}
@Override
public String toString(){
return name+""+id;
}
@Override
public int comparaTo(Object o){
Student st=(Student)o;
if(this.id==st.id)
return 0;
else if(this.id>st.id)
return 1;
else
return -1;
}
}
public class text{
public static void main(String[] args){
List L=new ArrayList();
L.add(new Student(1000,"张三"));//如果希望把对象放到List当中,必须要有一个比较标准,实现接口Comparable以及comparaTo方法
L.add(new Student(1001,"张四"));
L.add(new Student(1002,"张五"));
Collections.sort(L); //做过比较才能用Collections.()
System.out.println(L);
}
}
Set介绍:
set接口是Collection的子接口,set接口没有提供额外的方法,但实现set接口的容器类中的元素是没有顺序的,而且不可以重复。
Set容器可以与集合相对应。set的容器类有HashSet,TreeSet等。
eg:
class Student{
private String name;
private int id;
public Student(String name,int id){
this.name=name;
this.id=id;
}
@Override
public String toString(){
return name+""+id;
}
public Bolean equals(Object o){ //目的是去重复
Student st=(Student)o;
reutrn st.id==this.id&&st.name==this.name;
}
public int hashCode{ //目的是去重复,hashCode():表示 对象在内存中那个地址的十六进制。
return id * this.name.hashCode();//return new String(name+id).hashCode();
}
}
public class text{
public static void main(String[] args){
Set L=new HashSet(); //TreeSet不需要重写equals和hashCodes
L.add(new Student(1000,"张三"));
L.add(new Student(1001,"张四"));
L.add(new Student(1001,"小娟"));//想要去重复必须重写equals和hashCode
L.add(new Student(1001,"枉死"));
L.add(new Student(1002,"张五"));
System.out.println(L);
}
}
重写hashode方法的必要
String 和 Integer 这些Java自带的类都重写了hashCode方法,如果String 和Integer new 出来的对象的内容是一样的,则这些对象的hashCode返回值也是一样的,尽管这些对象占用的是不同的内存。
不过用户自定义类型则不同,如果程序的A类,即便是两个内存一模一样的A类对象,它们返回的hashCode值也是不一样的,但是两个内容一模一样的integer类对象或者String类对象返回的hashCode值却是一样的,因为系统自带的String和Integer 类都已经重写了Object的hashCode方法。
如果程序员希望自己定义的类对象,占用不同内存空间但内存却是一样的对象调用hashCode方法返回值一样的,则程序员就必须自己重写hashCode方法。
什么容器必须的重写equals方法和hashCode方法
添加到hashMap和hashtable容器中的键必须的同时实现equals()方法和hashCode()方法,否则很可能导致容器中出现重复的映射,所谓重复映射是指同一个键值映射在容器中出现了多次。
添加到hashSet容器中的对象也必须得同时实现equals()方法和hashCode()方法,否则很可能导致容器中出现重复的对象。
TreeSet和TreeMap则不需要实现equals()方法和hashCode()方法
注意:
向HashSet中添加对象时,HashSet先通过该对象的hashCode()计算出相应的桶,然后再根据equals()方法找到相应的对象,如果容器中已经存在该对象则不再添加,如果不存在,则添加进去。
怎样重写equals()方法和hashCode()方法
如何重写equals()
public boolean equals(Object obj)
{
如果this和ojb的内容是一模一样的
返回true
否则
返回false
}
如何重写hashCode()方法
public int hashCode()
{
return 当前类中基本类型数据对象的hashCode()方法
}