容器
容器的概率
容器API
Collection接口
Iterator接口
增强for循环
Set接口
List接口和Comparable接口
Collections类
Map接口
自动打包/解包
泛型
1、容器就是装其它各种各样对象的东西。数组是不可变长的,如果想储存更多的数据,就需要重新定义更大的数组,来复制过来。
2、JDK给我们提供了许多的容器
3、在这张里我们要记住1136(一个图,一个类,三个知识点,六个接口)
4、Java给我们提供的一些工具类java.util包中。
左边都是一个一个馒头来装的,右边都是一对一对馒头来装的。
左边Collection是一个接口,它提供了一个一个容器能够对外提供的方法,就像一个一个标准。
它的两个子接口:Set和List
Set他就像集合一样,没有顺序不可重复。
List有顺序并且可以重复。(两个对象怎样算是重复呢?如果这两个对象相互equals,相等了,那就说重复了。)
Map键值对的存储方法。
Collection接口中所定义的方法
:int size()
Boolean isEmpty()
void clear()
boolean contains(Object element)
boolean add(Object element)
boolean remove(Object element)
Iterator iterator();
boolean containsAll(Collection c)//是不是包含另一个集合中全部元素。
boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean retainAll(Collection c)//与参数集合求交集。
Object[] toArray();//将集合里装的对象转换成一个Object数组
集合里装的必须都是Object,直接打印一个集合,它会分别调用每一个元素的toString()方法
调用remove方法,比较的是参数与集合中的某个对象是否equals,如果equals的话,就删掉它。
在这里小小声明一下Integer和String都重写了toString()方法和equals()方法
5、容器类对象在调用remove()方法、contains()等方法是需要比较对象是否相等,这会涉及到对象类型的equals()方法和hashCode()方法;对于自定义的类型,需要重写equals()方法和hashCode()方法以实现自定义的对象相等规则。
注意:相等的对象应该具有相等的hash codes
主要用到equals()方法,有时候用到hashCode()方法,当这个对象在Map接口里头作为键,也就是作为字典里的索引。
相等的对象,如果两个对象互相equals,那他们就必须具备相等的hash codes
Object类中有一个hashCode()方法,可以找到它在内存中的地址
public int hashCode(),
从写equals()方法必须重写hashCode()方法
在eclipse源码中使用自动生成代码的话,equals()方法和hashCode()方法总是同时生成。
hashCode 的常规协定是: (摘自API文档)
· 在 Java 应用程序执行期间,在同一对象上多次调用hashCode 方法时,必须一致地返回相同的整数,前提是对象上equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
· 如果根据equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用hashCode 方法都必须生成相同的整数结果。
· 以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
当此方法被重写时,通常有必要重写 hashCode 方法,以维护hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。(摘自API文档)
object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode()
以上摘自博客园的一篇博客
http://www.cnblogs.com/happyPawpaw/p/3744971.html链接地址
我感觉equals()方法和hashCode()方法,为了遵守那个hashCode常规协定,而需要重写,但是也不是非要重写。
1、当你这个对象作为索引的时候,用到这个hashCode()方法。
2、Iteartor接口,用来遍历集合
在API文档中,Collection接口继承了Iterable接口,而Itreable接口中有Iteartor<> itreator()这个方法。那么Collection接口也就有了这个方法,返回一个在一组 T 类型的元素上进行迭代的迭代器。通过这个方法我们可以接收到一个迭代器,说白了,就是返回一个Itreator接口的对象,通过这个对象我们可以调用Iterator接口中的方法boolean hasNext()、next()、remove()方法。
当我们调用itreator()方法时,它会开辟一个临时的空间,会分配内存。
当迭代器对集合中某个元素访问时,首先对这个元素进行锁定,就是给这个元素上个锁,只有该迭代器可以对其进行访问。
3、有时候代码不敲一遍真是不知道自己原来还有那么多不会的东西,就像那个next()方法,我开始一直将N大写,
还有for循环遍历,那个Iterator t=collection.iterator()也要放在for循环里,并且用分号隔开。
在for(int i:array) 和for(Object o:collection)遍历中,其实就相当于调用了iterator方法。
4、List很像一个数组,它是一个有顺序可重复的集合。ArrayList底层是以数组实现的,LinkedList底层是以链表实现的
5、Object get(int index);//返回
6、Object set(int index,Object element)//返回的是原来的元素。
7、void add(int index,Object element)
8、Object remove(int index)
9、int indexOf(Object o)
10、int lastIndexOf(Object o);
11、java.util.Collections提供了一些静态方法实现了基于List容器的一些常用方法。
void sort(List)//排序
void shuffle(List)//对List进行随机排序
void reverse(List)//逆序
void fill(List,Object)//用一个特定的对象重写整个List容器
void copy(List des,List src)复制
Int binarySearch(List,Object)//二分法查找。
其中我想说的是那个copy()方法,起初如果刚定义一个目标容器,肯定会抛出越界异常,必须还要用个for循环往里添加一些空对象,用null表示就可以了。并且要保证你添加的对象要大于等于源容器。
12、Comparable接口实现了Comparable接口的类通过实现comparaTo()方法从而确定该类对象的排序方式。
已经有Authenticator.RequestorType,BigDecimal,BigInteger, Boolean,Byte,ByteBuffer,Calendar,Character,CharBuffer,Charset,CollationKey,CompositeName,CompoundName,Date,Date,Double, DoubleBuffer,ElementType,Enum,File,Float, FloatBuffer,Formatter.BigDecimalLayoutForm,FormSubmitEvent.MethodType,GregorianCalendar,IntBuffer,Integer,JTable.PrintMode,KeyRep.Type,LdapName,Long,LongBuffer,MappedByteBuffer,MemoryType,ObjectStreamField,Proxy.Type,Rdn,RetentionPolicy,RoundingMode,Short,ShortBuffer,SSLEngineResult.HandshakeStatus,SSLEngineResult.Status, String,Thread.State,Time,Timestamp,TimeUnit,URI,UUID
这些类实现了Comparable接口,可以重写Comparable接口中的方法,以比较两个对象的大小。
这些类都已经重写了comparaTo()方法,如果你想比较你定义的类的对象大小,就要继承Comparable接口,这样我们对装你定义的类的集合中的对象进行排序的时候虚拟机会自动调用你这个类的对象的comparaTo()方法,再来进行排序,注意:Comparable接口是在java.lang包里面的,只有java.lang包中才可以不用导入的。
将来我们该如何选择
Array读快改慢
Linked改快读慢
Hash两者之间
2、实现Map接口的类用来存储键-值对
3、实现Map接口的实现类有HashMap和TreeMap等。
4、 Map中键不可重复(索引),仍然说的是equals,比较equals()特别麻烦,直接比较每个对象的hashCode()方法。
5、方法Object pub ( Object key, Object value);//插入一个键值对,如果有了key这个索引,那就将原先key对应的value引换成现在的,并将原先的value返回回去。
Object get ( Object key );//获取
Object remove ( Object key ) ;//删除,比较的是hashCode()方法,应该是hashCode()方法。
boolean containsKey( Object key );//键(索引)是否包含在里面,hashCode()方法
boolean containsValue( Object value);//值是否包含在里面
int size()//有多少对
boolean isEmpty();//是否为空
void putAll ( Map t );//将一个Map中的元素都添加进来。
void clear();//从此映射中移除所有映射关系(可选操作)。
再次附上一篇讲关于环境变量配置的博客
http://www.cnblogs.com/my20121117/articles/3031703.html
6、jdk1.5之后就增加了自动打包和自动解包,将一个基础数据类型变成一个对象称为打包,将一个对象变成基础数据类型,称为解包。
map.put ( “one”, new Integer(1))完全可以写成map.put(“one”, 1 );可以自动打包成为一个对象。
int i=(Integer)map.get(“one”);可以直接用基础数据类型变量接收一个对象,这是因为java自动将我们解包。
http://www.cnblogs.com/smiles125/p/5370204.html
讲关于Map接口的实现类HashMap和TreeMap类得分区别,有时间再看。