Java的集合框架
java的集合框架
作用:解决了数组不可变的问题
Java的集合框架包括以下内容:
四个接口的区别:
1.collection:存储无序不唯一的数据
2.list:存储有序的,不唯一的数据
3.set:存储无序的,唯一的数据
4.Map:以键值对的形式存储数据,以键取值。键不能重复,值可以重复
一、List接口
1、ArrayList接口
常用的方法:
①add():在列表的最后添加元素;
②add(index,obj):在列表的指定位置添加元素;
③.size():返回当前元素列表的个数;
④get(intdex):返回下标为index的元素;
⑤clear():清除列表中的所有元素;
⑥contains():传入一个对象,检测列表中是否包含该对象;
如果传入的是String和基本数据类型,可以直接比对
如果传入的是实体对象,则默认只比对两个对象的地址,因此,只需要在实体类中重写equals()方法.
如何重写equals方法:
//在实体类News中重写equals方法,以title作为比较 @Override public boolean equals(Object obj) { if (this == obj)//检测是否为同一个引用 return true; if (obj == null)//如果传入的对象为空 return false; if (getClass() != obj.getClass())//两者的类型不同 return false; if(!(obj instanceof News)){//不比较可能会有空指针异常 return flase; } News other = (News) obj;类型相同,则比较内容 if (title == null) { if (other.title != null) return false; } else if (!title.equals(other.title)) return false; return true; }
ArrayList实现了一i个长度可变的数组,在内存中开辟一连串的空间,与数组的区别在于长度可以随意修改。这种存储结构在循环遍历和随机访问元素的速度比较快。
2.LinkedList接口
特有的方法:
①addFirst():开头插入元素
addLast():结尾插入元素
②removeFirst():删除第一个元素,并返回被删除的元素
removeLast():删除最后一个元素,并返回被删除的元素
③getFirst():返回列表第一个元素,但不会删除
getLast():返回列表的最后一个元素
迭代器 遍历列表
优点:使用迭代器遍历列表,不用担心下标越界问题
步骤:①使用列表调用.iterator()返回一个迭代器对象
②使用迭代器对象调用hasNext()判断是否有下一条数据
③使用迭代器对象调用.next()取出下一条数据
//新建集合,并传入数据 ArrayList<News> list1=new ArrayList<News>(); list1.add(new News(1,"asdfa","afasdf")); list1.add(new News(2,"asdfa","afasdf")); list1.add(new News(3,"asdfa","afasdf")); list1.add(new News(4,"asdfa","afasdf"));
//定义迭代器 Iterator<News> iter=list1.iterator(); while(iter.hasNext()){ News news=iter.next(); System.out.println(news.getTitle()+" "+news.getAuthor()); }
二、set接口
set接口中的元素是无序的,因此没有与下标相关的方法
1、HashSet
底层是调用HashMap的相关方法,传入数据后,根据数据的HashCode进行散列运算,得到一个散列值后再进行运算,确定元素在序列中的存储位置
HashSet如何判断多个对象是否相等
①先判断对象的HashCode,如果HashCode不同,则不是同一个对象,如果相同,则,继续判断equals()方法
②重写equals方法
所以,使用HashSet存储实体对象时,,必须要重写对象的HashCode()和equals()方法
//重写HashCode() @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((title == null) ? 0 :title.hashCode()); return result; }
2、LinkedHashSet
在HashSet的基础上,新增了一个链表
用链表来记录HashSet中元素的顺序,因此使用迭代器遍历时,可以按照放入的顺序依次读出元素
3、TreeSet
将存入的数据,先排序,再进行输出
如果存入的是实体对象,实体类必须实现Comparable接口,并重写compareTo()方法
class Person implements Comparable{ private int id; private String name ; private int age; public Person() { super(); } public Person(int id, String name, int age) { super(); this.id=id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int compareTo(Object o) { Person p = null; if(o instanceof Person){ // 如果传入的是本类示例,将向下转型 p = (Person) o; }else{ return 0; } return this.id-p.getId();//按照id升序排列 }
如果不实现接口:
可以在实例化TreeSet的同时,通过构造函数传入一个比较器
比较器:一个实现了Comparator接口,并重写了compare()方法的实现类的对象
//使用匿名内部类,拿到一个 比较器对象 Set<Person> set=new TreeSet<Person>(new Comparator(){ public int compare(Person p1, Person p2){ return p1.getId()-p2.getId(); } });
//或者自定义一个比较类,实现compare()接口
set<Person> set =new TreeSet<Person>(new Compare()); class Compare implements Comparator(){ //重写compare方法 @override public int compare(Person p1,person p2){ return p1.getId()-p2.getId(); } }
三、Map接口
特点:以键值对的形式存储数据,以键取值
常用方法:
①put(k,v):向Map的最后追加一个键值对
②get(k):通过键获取值
③clear():清空
④containsValue(obj):检测是否含有指定的值,返回true/flase
containsKey(obj):检测是否包含有指定的值
HashMap和Hashtable的区别
1、HashMap线程 不安全,Hashtable线程安全
2、HashMap键可以为空,Hashtable键不能为空
3、HashMap继承自AbstractMap,Hashtable继承在Dictionary类
4、HashMap的初始容量为16,Hashtable的初始容量为11
5、HashMap扩容为当前的2倍,Hashtable扩容为当前的2倍+1
6.、HashMap用ContainsKey()判断是否含有某个键,Hashtable用get()判断
LinkedHashMap
可以使用链表,记录数据放入的次数,进入与读出的顺序一致,与LinkedHashSet一致
TreeMap
key不能为null
根据键的顺序进行排序后输出
如果传入的是实体对象,必须重写比较方法
遍历Map的三种方式
一、以键取值
Set<String> keys= map1.keySet(); Iterator<String> iter1= keys.iterator(); while(iter1.hasNext()){ String key=iter1.next(); System.out.println(key+" "+map1.get(key)); }
二、直接遍历拿到每一个值
Set<String> keys= map1.keySet(); Iterator<String> iter1= keys.iterator(); while(iter1.hasNext()){ String key=iter1.next(); System.out.println(key+" "+map1.get(key)); }
三、
Set<Entry<String, String>> set2=map1.entrySet(); Iterator<Entry<String, String>> iter3=set2.iterator(); while(iter3.hasNext()){ Entry<String, String> entry=iter3.next(); //entry是Java提供的一种特殊的数据类型,其实就是一个键值对 //键就当前这条记录的键,使用getKey()取到 //值就当前这条记录的值,使用getValue()取到 System.out.println(entry.getKey()+"----"+entry.getValue()); } 或者 for (Entry<String, String> entry : set2) { System.out.println(entry.getKey()+"----"+entry.getValue()); }