Java容器

来源:互联网 发布:圆方软件怎么样 编辑:程序博客网 时间:2024/06/15 07:13

1.泛型和类型安全的容器:


ArrayList arrayList = new ArrayList();
现在初始化的ArrayList的长度其实是10;根据javaJDK可知。


2.Arrays.asList():

package collection.arrayList;
 
import java.util.ArrayList;
import java.util.Arrays;
 
public class ArrayListAddArray {
 
public static void main(String[] args){
Integer[] array = {new Integer(1),new Integer(1),new Integer(1),new Integer(1),new Integer(1)};
ArrayList arrayList = new ArrayList();
arrayList.add(array);
for(int i=0;i<arrayList.size();i++){
System.out.println(arrayList.get(i));
}
arrayList.remove(0);
arrayList.add(Arrays.asList(array));
for(int i=0;i<arrayList.size();i++){
System.out.println(arrayList.get(i));
}
}
 
}
当把一个数组对象直接add到ArrayList中的时候,其实是add的这个数组对象的引用,而不是数组元素。只有通过Arrays.asList()才能才是向其中增加的数组元素。

3.ArrayList和LinkedList的比较:

1).ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2).对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3).对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 
不过这个总结说的似乎也不尽然,这个似乎跟操作的数据多少有关系。

4.Iterator:

package collection.arrayList;
 
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
 
public class IteratorWithRemove {
 
public static void main(String[] args){
Collection book = new HashSet();
book.add("java编程思想!");
book.add("Effective java!");
book.add("Head first!");
Iterator iterator = book.iterator();
while(iterator.hasNext()){
String bookStr = (String) iterator.next();
System.out.println(bookStr);
if(bookStr.equals("java编程思想!")){
iterator.remove();
}
}
System.out.println(book);
}
}
Iterator只用于遍历集合,而其自身没有承装集合的能力。如果想创建一个Iterator对象,必须有一个集合调用Iterator()方法。
package collection.arrayList;
 
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
 
public class IteratorWithRemove {
 
public static void main(String[] args){
Collection book = new HashSet();
book.add("java编程思想!");
book.add("Effective java!");
book.add("Head first!");
System.out.println(book);
Iterator iterator = book.iterator();
while(iterator.hasNext()){
String bookStr = (String) iterator.next();
System.out.println(bookStr);
if(bookStr.equals("java编程思想!")){
//iterator.remove();
book.remove(bookStr);
}
}
System.out.println(book);
}
}
从上面看出,20和21行的效果是相同的。

5.Set:

          Set判断两个对象是否相同不是用的“==”,而是用的equals。
         对象想放到Set集合或者是想作为Map的key时,那么你必须重写equals()方法,这样才能保证唯一性。当然,在这种情况下,你不想重写hashCode()方法,也没有错。但是,对于良好的编程风格而言,你应该在重写equals()方法的同时,也重写hashCode()方法。
package collection.arrayList;
 
import java.util.HashSet;
import java.util.Set;
 
public class SetForObject {
public static void main(String[] args){
Set testSet = new HashSet();
String str1 ="java";
String str2 = new String("java");
testSet.add("java");
boolean result = testSet.add(str1);
boolean equalsResult = str1.equals(str2);
System.out.println(result);
System.out.println(equalsResult);
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
}
 
}
      上面运行的结果:。说明当equals为true的时候就会添加失败,而不会管hashCode是否相同。

6.HashSet:

1).  HashSet按Hash算法来存储集合中的元素,因此具有很好的存储和查找性能。
2).HashSet的特点:
不能保证元素的排列顺序,元素的排列顺序有可能发生变化;
HashSet不是同步的,多个线程操作同一个HashSet的时候需要用代码来保证同步;
集合的元素可以为null。
3).HashSet是基于HashMap来实现的,底层采用HashMap来保存数据。HashSet的没一个值都是保存在HashMap的key中。如下面代码所示:
public Iterator<E> iterator() {
return map.keySet().iterator();
}
        iterator() 方法返回对此 set 中元素进行迭代的迭代器。返回元素的顺序并不是特定的。底层调用HashMap的keySet返回所有的key,这点反应了HashSet中的所有元素都 是保存在HashMap的key中,value则是使用的PRESENT对象,该对象为static final。
4).HashSet的相关方法:
public int size() {
return map.size();
}
size()返回此 set 中的元素的数量(set 的容量)。底层调用HashMap的size方法,返回HashMap容器的大小。
public boolean isEmpty() {
return map.isEmpty();
}
isEmpty(),判断HashSet()集合是否为空,为空返回 true,否则返回false
public boolean contains(Object o) {
return map.containsKey(o);
}
 contains(), 判断某个元素是否存在于HashSet()中,存在返回true,否则返回false。更加确切的讲应该是要满足这种关系才能返回true: (o==null ? e==null : o.equals(e))。底层调用containsKey判断HashMap的key值是否为空。

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
add() 如果此 set 中尚未包含指定元素,则添加指定元素。如果此Set没有包含满足(e==null ? e2==null : e.equals(e2)) 的e2时,则将e2添加到Set中,否则不添加且返回false。由于底层使用HashMap的put方法将key = e,value=PRESENT构建成key-value键值对,当此e存在于HashMap的key中,则value将会覆盖原有value,但是 key保持不变,所以如果将一个已经存在的e元素添加中HashSet中,新添加的元素是不会保存到HashMap中,所以这就满足了HashSet中元 素不会重复的特性。
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
 remove如果指定元素存在于此 set 中,则将其移除。底层使用HashMap的remove方法删除指定的Entry。
public void clear() {
map.clear();
}
clear从此 set 中移除所有元素。底层调用HashMap的clear方法清除所有的Entry。
public Object clone() {
try {
HashSet<E> newSet = (HashSet<E>) super.clone();
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
clone返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。
5).add(E e)方法:
当向一个HashSet中存入一个元素的时候,HashSet对象会调用hashCode()方法来获取这个元素的hashCode值,根据HashCode值来确定元素的存储位置。如果两个元素通过equals()方法比较为true,但是调用hashCode()方法返回的hashCode的值不同,那么这两个元素也会存储到不同位置。HashSet判断两个元素相同的方法是,equals()方法返回为true,hashCode的值相同。
如果把一个对象存入到HashSet中要重写这个对象的equals()方法和hashCode()方法。而且需要保证当equals()方法返回为true的时候,哈市Code()方法返回值应该相同。

7.TreeSet:

1.TreeSet是SortedSet接口的唯一实现,TreeSet可以确保元素处于排序状态。
2.TreeSet是采用红黑树的数据结构对数据进行排序。TreeSet支持两种排序方法:自然排序和定制排序。
3.自然排序:
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后让集合按照升序排列。
BigDecimal、BigIneger以及所有数值型对应包装类:按它们对应的数值的大小进行比较。
Character:按字符的UNICODE值进行比较。
Boolean:true对应的包装类实例大于false对应的包装类实例。
String:按字符串中字符的UNICODE值进行比较。
Date、Time:后面的时间、日期比前面的时间、日期大。
4.TreeSet插入类对象:
当像TreeSet集合中添加类对象的时候,该类必须实现Comparable接口。否则程序就会出现异常。
package collection.arrayList;
 
import java.util.Set;
import java.util.TreeSet;
 
public class TreeSetAddObject {
 
public static void main(String[] args) {
Set ts = new TreeSet();
ts.add(new Error());
ts.add(new Error());
}
 
}
运行结果如下:

当采用compareTo(Object obj)方法比较对象时,都需要将被比较对象obj强制类型转换成相同类型,因为只有相同类的两个实例才能比较大小。即向TreeSet中添加的应该是同一个类的对象,否则会引发ClassCastException异常。
package collection.arrayList;
 
import java.util.Date;
import java.util.TreeSet;
 
public class TreeSetMustAddSameObject {
 
public static void main(String[] args){
TreeSet ts = new TreeSet();
ts.add(new String("TreeSet"));
ts.add(new Date());
}
}
运行结果如下:

当使用TreeSet存储数据的时候,如果两个对象的equals()方法返回值相同,那么这两个对象的CompareTo(Object obj)方法返回值也必须相同。
class Teacher implements Comparable {
int num;
String name;
 
Teacher(String name, int num) {
this.num = num;
this.name = name;
}
 
public String toString() {
return "学号:" + num + "\t\t姓名:" + name;
}
 
//o中存放时的红黑二叉树中的节点,从根节点开始比较
public int compareTo(Object o) {
Teacher ss = (Teacher) o;
int result = num < ss.num ? 1 : (num == ss.num ? 0 : -1);//降序
//int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);//升序
if (result == 0) {
result = name.compareTo(ss.name);
}
return result;
}
}
Set接口的实现类都是线程不安全的,当有多个线程访问Set集合的时候需要手动同步。

8.List

void add(int index,Objec obj):将obj插入到List的指定的index处;
package collection.arrayList;
 
import java.util.ArrayList;
import java.util.List;
 
public class ListTestMethod {
 
public static void main(String[] args) {
List list = new ArrayList();
list.add("list1");
list.add("list2");
list.add("list3");
System.out.println(list);
list.add(1, "list4");
System.out.println(list);
}
 
}
运行结果:

但是,这个index不能超过list的长度负责出异常。
package collection.arrayList;
 
import java.util.ArrayList;
import java.util.List;
 
public class ListTestMethod {
 
public static void main(String[] args) {
List list = new ArrayList();
list.add("list1");
list.add("list2");
list.add("list3");
System.out.println(list);
list.add(1, "list4");
System.out.println(list);
System.out.println(list.size());
list.add(4,"list5");
System.out.println(list);
}
 
}
运行结果:


package collection.arrayList;
 
import java.util.ArrayList;
import java.util.List;
 
public class ListTestMethod {
 
public static void main(String[] args) {
List list = new ArrayList();
list.add("list1");
list.add("list2");
list.add("list3");
System.out.println(list);
list.add(1, "list4");
System.out.println(list);
System.out.println(list.size());
list.add(5,"list5");
System.out.println(list);
}
 
}
运行结果:

由此可见,使用该方法的时候只能操作当前长度的List,如果超出当前长度就会报异常。









 






0 0
原创粉丝点击