- 浏览: 56867 次
- 性别:
- 来自: 郑州
文章分类
最新评论
-
咖啡骑士:
亲测有效,谢谢了,转一下哦
mybatis创建oracle触发器的问题 -
ocaicai:
我遇到的问题是:批量更新1000条数据,居然使用了13秒,在百 ...
jdbcTemplate.batchUpdate没有批量执行
Java中的集合:
为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
集合是存储对象的一个工具。
集合和数组的特点:
相同点:
数组和集合都是容器。
不同的:
集合:
1,可以存储对象,只能存储对象
2,集合的长度是可变的。
数组:
1,可以存储对象,也可以存储基本数据类型。
2,数据长度是固定的。
**容器对象有很多种,通过内部的数据结构来区分。
数据结构:就是一种数据存储的方式。
**容器在不断将共性向上抽取的过程中,就出现了集合体系结构。
该结构的顶层是一个接口,Collection。
Collection接口:
创建一个集合对象,也就是一个容器。
Collection coll = new ArrayList();
1,添加元素
Add(); coll.add(“abc”);
2,删除元素
Boolean b = coll.remove(“abc”);
3,获取集合的长度
Int size = coll.size();
4,清除集合中的所有元素
Coll.clear();
5,判断集合是否为空(其实依据的是size()是否等于0判断的)
Boolean b = coll.isEmpty();
6,添加一堆元素
coll.addAll(Collection co1);//添加的是一个集合
7, 判断一堆元素是否存在
coll.containsAll(Collection co1);
8,删除一堆元素
Boolean b = coll.removeAll(Collection co1);
9,获取两个集合的交集。
Boolean b = coll.retainAll(co1);
//retainAll会将coll和co1中相同的元素保留在coll中,所以coll中存储的就是交集的元素,当coll集合中的元素变化时,retainAll方法返回的是true,当coll集合中的元素本身就是交集元素,不发生变化,返回false。
10,Collection集合中对元素的获取方法。
Coll.iterator();
**集合容器都具备取出方式,取出方式并不是一个方法。因为一个方法不足以完成取出功能。
取出是由多个功能来完成,为了方便使用,就将这些功能封装成对象。该对象在描述这些功能会直接使用到具体集合中的数据和集合特点。
所以这个取出元素的描述类,定义在了集合的内部。也就是一个内部类。
因为这个类直接访问集合中的数据,根据集合自身的数据结构特点。将具体的方法都定义完成后。需要将对象提供出去。让用户使用。所以暴露了一个方法来完成对这个内部类对象的访问。
为了提高扩展性,发现只要是容器,就具备取出功能。但是数据结构不同,取出的具体实现就不一样,这时为了扩展,就抽取出了一个接口。Iterator。
取出对象有两种表现形式:
1,Iterator it = coll.iterator();
While(it.hasNext()){
System.out.println(it.next());
}
2,for(Iterator it = coll.iterator(); it.hasNext(); ){
System.out.println(it.next());
}
第二种可以减少内存的消耗,因为第一种的it使用完之后还存在,而在for循环中,it出了for循环就不存在了
容器在进行添加的时候add();中的参数是object类型。
那么在取出的时候就要写成
Person p1 = (Person)it.next();
所以在进行迭代器使用的时候,next方法在循环中,建议只定义一个,定义多个会导致数据错误。当next方法没有获取到元素时,会发生NoSuchElementException;
**其实集合中存储的都是对象的引用。
获取迭代器后,迭代器中持有的也是元素的引用。
Collection
|--List:该容器的元素是有序的 (存储的顺序和取出的顺序一致)
该集合中的元素都有索引 (角标) ,该集合可以存储重复的元素
|--ArrayList:底层数据结构是数组结构 不同步的,查询的速度很快
|--vector:底层数据结构是数组结构 jdk1.0版本。 同步的
|--LinkedList:底层数据结构是链表结构 不同步的,对元素的增删操作效率很高
(vector和ArrayList区别?
Vector相对于线程时安全的,同步的。ArrayList是不安全的
)
|--Set:无序,不可以存储重复元素。Set接口的方法与collection方法一致。
Set没有特殊方法。Set接口取出元素方法只有迭代器。
|--HashSet:底层数据结构是哈希表。哈希表这种结构,就是对哈希值的存储。而且 每一个对象都有自己的哈希值。因为object类中有个hashCode方法。
(如何保证元素唯一性?
通过判断元素的hashCode方法,和equals方法来完成的。当hashCode值相同,会再判断一次equals方法的返回值是否为true。
如果hashCode值不同,就确定元素的哈希表中的位置,不同判断equals了。
哈希表中有一个桶结构,每一个桶都有一个哈希值,当哈希值相同,但是equals为false时,这些元素都放在同一个桶中。
)
|--TreeSet:可以对set集合中的元素进行排序。
数据结构是二叉树,这种结构,可以提高排序性能。
(如何保证元素唯一性?
是根据比较方法的返回值确定的,只要返回的是0,就代表元素重复。
)
List:常用的共性方法。(继承了Collection接口)
1,添加元素。
Add(index,element);//在索引位添加元素,其他元素依次顺延。
2,删除元素。
Remove(index);//按照指定索引删除元素。被删除的元素会被返回。
3,修改元素。
Set(index,element);//按照索引修改元素,被修改的元素会被返回。
4,获取元素。
Get(index);//通过索引获取指定元素
Get(element);//通过元素获取元素第一次出现的位置
subList(fromIndex,lastIndex);//根据头尾角标获取子列表。
通过List特有的方式,获取集合中所有的元素。(其实就是for循环)
For(int x = 0;x < list.size(); x++)
{
System.out.println(list.get(x));
}
**在进行迭代过程中,如果出现了迭代器和容器同时对元素进行操作的情况很容易引发
ConcurrentModificationException并发修改异常。
所以要么使用集合的方法操作元素,要么使用迭代器的方法操作元素,不要同时使用,
迭代器Iterator中只有三个操作,hasNext,next,remove,如果想进行添加,这个迭代器就不可以使用了,这时,可以使用一个新的迭代方式,ListIterator列表迭代器,ListIterator本身也是Iterator的接口,并且有更多的方法。
既然ArrayList底层是数组实现的,数组的长度是固定的,那么究竟是如何实现的呢?
ArrayList内部封装了一个默认长度为10的数组。当超出长度时,集合内部会自动生成一个新的数组,然后将原来的数组复制到新的数组中去。这就是导致ArrayList修改数据的效率比LinkedList慢的原因。
新的数组到底多长?
ArrayList 50%延长
Vector 100%延长
ArrayList判断元素是否相同,底层依据的是元素的equals方法。无论是contains还是remove都会去使用equals判断元素是否相同。所以在往ArrayList集合存储自定义元素时,最好建立该元素特有判断对象是否相同的依据。也就是需要覆盖equals方法。
LinkedList的特有方法:
1,
addFirst();
addLast();
在jdk1.6以后。
被offerFirst();
offerLast();替代
2,
getFirst(); 获取元素,集合的长度不改变
getLast();
在jdk1.6以后,被
peekFirst();
peekLast();替代。
3,
removeFirstt();获取元素,集合的长度改变
如果集合中没有元素,那么该方法会发生异常NoSuchElementException
removeFirst();
在jdk1.6以后,被
pollFirst();
pollLast();代替。
如果集合元素没有,不会抛异常,而是返回null
Vector:vector中提供了一个独特的取出方式,就是枚举
Enumeration。此接口Enumeration的功能与Iterator接口的功能是重复的。
Enumeration的名称和方法的名称过程,书写比较麻烦,并且Iterator有个移除的方法。
所以被Iterator取 代。
**如果在编译的时候如果出现了
{
注意:TestArrayList.java 使用了未经检查或不安全的操作。
注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
}
的提醒,并不是编译失败,是因为类型的原因导致的,如果用了泛型,就没有该提示了。
HashSet:
HashSet集合元素保证唯一性,依赖的是元素的hashCode方法和equals方法。
当元素的哈希值不同时,元素都有自己的独立位置。不需要再判断元素的equals方法,当元素的哈希值相同时,这时元素在哈希表中位置相同,这时就需要再判断元素的内容是否相同,就需要调用元素的equals方法进行一次比较。如果equals返回true,那么视为两个元素重复。只存储一个。如果返回false,那么这两个元素不是重复元素,会存储在同一个哈希值上。
为了建立自定义对象判断元素是否重复的依据。
需要覆盖hashCode方法,和equals方法。
而且最好依据对象的特有条件来建立hashcode和equals的实现。
ArrayList:判断包含,以及删除,都是依据元素的equals方法。
HashSet:判断包含,以及删除,都是依据元素的hashCode方法。当hashCode值相同时,再判断一次equals方法。
TreeSet:
TreeSet集合是用于给元素进行排序的。那么自定义元素本身不具备比较性,treeSet集合是无法对元素进行排序的。所以,在自定义对象时,需要对象具备一个扩展功能,用于比较的,而java已经提供了接口,可以让实现它的对系那个具备比较性。
那么自定义类,要想被treeSet排序,就要实现Comparable接口,以具备比较功能。
也可以将一个实现了Comparato接口的子类对象作为参数传递给TreeSet集合的构造函数即可,这样该集合就具备了比较功能。
TreeSet排序方式有两种:
1,让元素自身具备比较性
其实是让元素实现Comparable接口,覆盖CompareTo方法。这称为元素的自然排序。
2,当元素自身不具备比较性,或者元素具备的比较性不是所需要的,定义一个比较器。
其实就是定义一个类,实现Comparator接口,覆盖Compare方法。将comparator接口的子类对象作为参数传递给TreeSet的构造函数。
当元素自身具备比较性,同时TreeSet集合也具备比较器,这时以比较器为主。
所以建议使用第二种方法,比较灵活。
**一般在描述一个对象时,如果该对象封装了具体的数据,会出现很多这样的对象,这时就需要进行容器的存储。
那么描述该类对象时,一般要复写几个方法:
1,hashCode()
2,equals()
3,toString()
4,最好实现Comparable接口让该类具备自然排序功能。
建立对象自身判断是否相同的依据,同时让对象具备基本的比较性。
泛型:
泛型其实就是jdk1.5版本以后出现的一个安全机制。,泛型其实是给编译器使用的。
Al.add(3);//al.add(new Integer(3));因为jdk1.5之后有自动装箱,所以会自动把3装成对象。
集合中存储了不同类型的对象,取出时,容易在运行时时期发生classCastException类型转换异常。为了避免这个问题的发生,如果在存储的时候名气了集合要操作的数据类型,这样取就没有问题了。
就需要在定义集合时,就立刻明确元素的类型。
其实借鉴于数组。
可以通过<>来明确元素的类型。
ArrayList<String> al = new ArrayList<String>();
泛型的好处:
1,将运行时期出现的classCastException问题,转移到编译时期。
2,泛型的出现避免了强制转换的麻烦。
泛型的表现形式是<>;
什么时候使用泛型?
只要用到的类或者接口的旁边有<>的时候,就要明确具体类型。
泛型的使用其实就是给<>传递实际参数,而这个参数就是一个具体的引用数据类型。
什么时候使用泛型类?
当类要操作的引用数据类型不确定的时候,可以使用泛型来定义。
也就是定义一个类型参数。
具体要操作什么类型的对象,有使用该类的使用者来明确,将具体的类型作为实际参数传递给<>;
Class Tool<Q>
{
Private Q obj;
Public void setObj(Q obj){
This.obj = obj;
}
Public Q getObj(){
Return obj;
}
}
当泛型定义在类上,该泛型作用于整个类。当该建立对象时,就明确了具体类型。那么凡是使用了类上定义的泛型的方法,操作的类也就固定了。
当希望类中的方法,可以操作任意类型而不受类中泛型限制。
可以将泛型定义在方法上。泛型方法。
Public <Q> void print(Q q){
System.out.println(“print”+q);
}
当类中定义static方法时,静态方法是不可以直接访问类上的泛型。因为类上的泛型只有通过建立对象才能明确具体类型。
所以静态方法如果操作的引用数据类型不确定,只能将泛型定义在方法上。
(静态方法上定义泛型,必须定义在static关键字之后)
Public static<W> void method(W w){
System.out.prinln(method+”w”);
}
当方法中操作的应用数据类型不确定,而且和对应的对象执行的类型也不一定一致。
这时就将泛型定义在方法上。
泛型接口:
1,
Class InterImpl implements Inter<String>{
Public void show(String s){
System.out.println(s);
}
}
2,
Class InterImpl<T> implements Inter<T>{
Public void show(T t){
System.out.println(“show”+t);
}
}
泛型:通配符?代表任意类型。
Public static void show(Collection<?> coll){
Iterator<?> it = coll.iterator();
While(it.hasNext()){
System.out.println(it.next());
}
}
定义集合时要保证左右两边的类型一致。两边只有一边定义泛型,也是可以支持,至少新老版本兼容,但是一样会出现提示信息。
泛型限定:
定义T只能固定一种类型,定义?可以是任意类型,只想操作该类或该类的子类。要使用泛型限定。
? extends E:接收E类型或者E的子类型。
? super E:接收E类型或者E类型的父类型。
例如:
Public static void show(Collection<? extends Person> coll){
Iterator<? extends Person> it = coll.itrator();
While(it.hasNext()){
System.out.println(it.next());
}
}
集合框架中的另一个顶层接口:Map
Map集合的特点:
1,是一个双列集合,collection是单例集合
2,Map一次存一对元素,同时键值对的形式。建和值有对应关系,collection是一次存一个元素。
3,Map集合必须保证集合中键的唯一性。
Map集合中常见的功能:
1,添加
v put(k , v);将k和v作为元素存储如map集合,当存入相同的k时,
新的值会覆盖原来的值,并返回原来的值。
void putAll(map);
2,删除
Clear();
V remove(k):按照键删除,并返回被删除的键对应的值。
3,判断
Boolean containsKey(Object key)
Boolean containsValue(Object value);
Boolean isEmpty();
4,获取
Int size();获取map集合的元素个数
V get(k);通过键获取值。
Collection values();获取map集合中所有的值。
Set keySet():获取map集合中所有的键。
Set entrySet():获取的是键值的映射关系,将映射关系存入到set集合中。
Map集合没有迭代器。迭代器是collection集合具备的,Map集合的取出元素的原理就是将map集合先转成set集合,然后再进行迭代。
Map
|--Hashtable:底层是哈希表数据结构(同步的,不允许null作为键,null作为值)
|--properties:用于配置文件的定义和操作,使用频率非常高,同时键和值都是字符串。是集合中可以和IO技术相结合的对象。
|--HashMap:底层是哈希表数据结构(不同步的,允许null作为键,允许null作为值)
|--LinkedHashMap:可以保证hashMap存入顺序和取出顺序一致
|--TreeMap:可以用来对map集合中的键进行排序。
如何获取集合中的所有元素?
一:
1,获取所有的键,再通过对所有的键进行遍历,在遍历中通过get方法获取每一个键的对应的值,使用keySet方法获取map集合中键的集合。
2,对set集合进行迭代器的操作。
Set<Integer> keySet = hm.keySet();
Iteraror it = keySet.itertor();
While(it.hasNext()){
Integer i = it.next();
String s = hm.get(i);
System.out.println(s+”...”+i);
}
二:
1,将map集合中的键值关系取出,并封装成一个键值关系对象,再存储到一个set集合中。
键值映射关系封装对象后的数据类型是map.entry(内部接口)
Entry就是一个map接口中的内部静态接口。
作为一个键值关系的数据类型存在。
使用entrySet获取map集合中的所有键值。
Set<Map.Entry<Integer,String>> entry = hm.entrySet();
Iterator<Map.Enrty<Integer,String>> it = entrySet.iterator();
While(it.hasNext()){
Map.Entry<Integer,String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+”...”+value);
}
hashMap:参考HashSet
存入的对象是无序的,想要保证有序。可以使用子类LinkedHashmap。存入和取出的顺序是一致的。
TreeMap:参考TreeSet
Utility:集合中的工具类:
如果有一堆元素。
要是元素重复,选择ArrayList集合,但是想要让元素按顺序排序,可以使用集合中的工具类。
工具类有两种。collections,Arrays
这两个工具类的特点:类中的方法都是静态的,不需要创建对象。
1,collections
Collections是集合对象的工具类,提供了操作集合的工具方法。
Fill(al,”kk”);将集合中的元素替换成指定的元素kk。
Reverse(al);集合元素反转,头尾对调
Swap(al,2,4);对集合中的元素进行位置的置换
Shuffle(al);对集合中的元素进行随机的位置置换
toArray();将集合变成数组
给toArray方法传递一个指定类型的数组。
当指定的长度小于集合的长度,该方法会自动创一个该类型的新数组长度和集合长度一致。用于存储集合中的元素,如果指定的数组长度大于集合的长度,那么该方法就不会创建新数组,而是使用传递进来的数组,存储完集合的元素后,其他的未存储的位置为null。
将集合变成数组后,限定了对元素的增删操作。
Xxx synchronizedList(xxx);可以将一个不同步的集合转成一个同步的list集合
2,Arrays
Arrays:是数组的工具类,提供了堆数组的工具方法。
asList(arr);将数组变成集合。
当数组变成集合后,就可以使用集合的方法来操作数组,而不用自己再定义指针进行数组的操作。(有些方法不可以用,只要是改变集合长度的方法都不能用,因为数组是固定长度的)
当数组中的元素时引用数据类型时,变成集合后,就将数组中的元素作为集合中的元素存在,当数组中的元素时基本数据类型时,变成集合后,会将这个数组变成集合中的元素。
List<int[]> list = Arrays.asList(arr);
System.out.println(list);
为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
集合是存储对象的一个工具。
集合和数组的特点:
相同点:
数组和集合都是容器。
不同的:
集合:
1,可以存储对象,只能存储对象
2,集合的长度是可变的。
数组:
1,可以存储对象,也可以存储基本数据类型。
2,数据长度是固定的。
**容器对象有很多种,通过内部的数据结构来区分。
数据结构:就是一种数据存储的方式。
**容器在不断将共性向上抽取的过程中,就出现了集合体系结构。
该结构的顶层是一个接口,Collection。
Collection接口:
创建一个集合对象,也就是一个容器。
Collection coll = new ArrayList();
1,添加元素
Add(); coll.add(“abc”);
2,删除元素
Boolean b = coll.remove(“abc”);
3,获取集合的长度
Int size = coll.size();
4,清除集合中的所有元素
Coll.clear();
5,判断集合是否为空(其实依据的是size()是否等于0判断的)
Boolean b = coll.isEmpty();
6,添加一堆元素
coll.addAll(Collection co1);//添加的是一个集合
7, 判断一堆元素是否存在
coll.containsAll(Collection co1);
8,删除一堆元素
Boolean b = coll.removeAll(Collection co1);
9,获取两个集合的交集。
Boolean b = coll.retainAll(co1);
//retainAll会将coll和co1中相同的元素保留在coll中,所以coll中存储的就是交集的元素,当coll集合中的元素变化时,retainAll方法返回的是true,当coll集合中的元素本身就是交集元素,不发生变化,返回false。
10,Collection集合中对元素的获取方法。
Coll.iterator();
**集合容器都具备取出方式,取出方式并不是一个方法。因为一个方法不足以完成取出功能。
取出是由多个功能来完成,为了方便使用,就将这些功能封装成对象。该对象在描述这些功能会直接使用到具体集合中的数据和集合特点。
所以这个取出元素的描述类,定义在了集合的内部。也就是一个内部类。
因为这个类直接访问集合中的数据,根据集合自身的数据结构特点。将具体的方法都定义完成后。需要将对象提供出去。让用户使用。所以暴露了一个方法来完成对这个内部类对象的访问。
为了提高扩展性,发现只要是容器,就具备取出功能。但是数据结构不同,取出的具体实现就不一样,这时为了扩展,就抽取出了一个接口。Iterator。
取出对象有两种表现形式:
1,Iterator it = coll.iterator();
While(it.hasNext()){
System.out.println(it.next());
}
2,for(Iterator it = coll.iterator(); it.hasNext(); ){
System.out.println(it.next());
}
第二种可以减少内存的消耗,因为第一种的it使用完之后还存在,而在for循环中,it出了for循环就不存在了
容器在进行添加的时候add();中的参数是object类型。
那么在取出的时候就要写成
Person p1 = (Person)it.next();
所以在进行迭代器使用的时候,next方法在循环中,建议只定义一个,定义多个会导致数据错误。当next方法没有获取到元素时,会发生NoSuchElementException;
**其实集合中存储的都是对象的引用。
获取迭代器后,迭代器中持有的也是元素的引用。
Collection
|--List:该容器的元素是有序的 (存储的顺序和取出的顺序一致)
该集合中的元素都有索引 (角标) ,该集合可以存储重复的元素
|--ArrayList:底层数据结构是数组结构 不同步的,查询的速度很快
|--vector:底层数据结构是数组结构 jdk1.0版本。 同步的
|--LinkedList:底层数据结构是链表结构 不同步的,对元素的增删操作效率很高
(vector和ArrayList区别?
Vector相对于线程时安全的,同步的。ArrayList是不安全的
)
|--Set:无序,不可以存储重复元素。Set接口的方法与collection方法一致。
Set没有特殊方法。Set接口取出元素方法只有迭代器。
|--HashSet:底层数据结构是哈希表。哈希表这种结构,就是对哈希值的存储。而且 每一个对象都有自己的哈希值。因为object类中有个hashCode方法。
(如何保证元素唯一性?
通过判断元素的hashCode方法,和equals方法来完成的。当hashCode值相同,会再判断一次equals方法的返回值是否为true。
如果hashCode值不同,就确定元素的哈希表中的位置,不同判断equals了。
哈希表中有一个桶结构,每一个桶都有一个哈希值,当哈希值相同,但是equals为false时,这些元素都放在同一个桶中。
)
|--TreeSet:可以对set集合中的元素进行排序。
数据结构是二叉树,这种结构,可以提高排序性能。
(如何保证元素唯一性?
是根据比较方法的返回值确定的,只要返回的是0,就代表元素重复。
)
List:常用的共性方法。(继承了Collection接口)
1,添加元素。
Add(index,element);//在索引位添加元素,其他元素依次顺延。
2,删除元素。
Remove(index);//按照指定索引删除元素。被删除的元素会被返回。
3,修改元素。
Set(index,element);//按照索引修改元素,被修改的元素会被返回。
4,获取元素。
Get(index);//通过索引获取指定元素
Get(element);//通过元素获取元素第一次出现的位置
subList(fromIndex,lastIndex);//根据头尾角标获取子列表。
通过List特有的方式,获取集合中所有的元素。(其实就是for循环)
For(int x = 0;x < list.size(); x++)
{
System.out.println(list.get(x));
}
**在进行迭代过程中,如果出现了迭代器和容器同时对元素进行操作的情况很容易引发
ConcurrentModificationException并发修改异常。
所以要么使用集合的方法操作元素,要么使用迭代器的方法操作元素,不要同时使用,
迭代器Iterator中只有三个操作,hasNext,next,remove,如果想进行添加,这个迭代器就不可以使用了,这时,可以使用一个新的迭代方式,ListIterator列表迭代器,ListIterator本身也是Iterator的接口,并且有更多的方法。
既然ArrayList底层是数组实现的,数组的长度是固定的,那么究竟是如何实现的呢?
ArrayList内部封装了一个默认长度为10的数组。当超出长度时,集合内部会自动生成一个新的数组,然后将原来的数组复制到新的数组中去。这就是导致ArrayList修改数据的效率比LinkedList慢的原因。
新的数组到底多长?
ArrayList 50%延长
Vector 100%延长
ArrayList判断元素是否相同,底层依据的是元素的equals方法。无论是contains还是remove都会去使用equals判断元素是否相同。所以在往ArrayList集合存储自定义元素时,最好建立该元素特有判断对象是否相同的依据。也就是需要覆盖equals方法。
LinkedList的特有方法:
1,
addFirst();
addLast();
在jdk1.6以后。
被offerFirst();
offerLast();替代
2,
getFirst(); 获取元素,集合的长度不改变
getLast();
在jdk1.6以后,被
peekFirst();
peekLast();替代。
3,
removeFirstt();获取元素,集合的长度改变
如果集合中没有元素,那么该方法会发生异常NoSuchElementException
removeFirst();
在jdk1.6以后,被
pollFirst();
pollLast();代替。
如果集合元素没有,不会抛异常,而是返回null
Vector:vector中提供了一个独特的取出方式,就是枚举
Enumeration。此接口Enumeration的功能与Iterator接口的功能是重复的。
Enumeration的名称和方法的名称过程,书写比较麻烦,并且Iterator有个移除的方法。
所以被Iterator取 代。
**如果在编译的时候如果出现了
{
注意:TestArrayList.java 使用了未经检查或不安全的操作。
注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
}
的提醒,并不是编译失败,是因为类型的原因导致的,如果用了泛型,就没有该提示了。
HashSet:
HashSet集合元素保证唯一性,依赖的是元素的hashCode方法和equals方法。
当元素的哈希值不同时,元素都有自己的独立位置。不需要再判断元素的equals方法,当元素的哈希值相同时,这时元素在哈希表中位置相同,这时就需要再判断元素的内容是否相同,就需要调用元素的equals方法进行一次比较。如果equals返回true,那么视为两个元素重复。只存储一个。如果返回false,那么这两个元素不是重复元素,会存储在同一个哈希值上。
为了建立自定义对象判断元素是否重复的依据。
需要覆盖hashCode方法,和equals方法。
而且最好依据对象的特有条件来建立hashcode和equals的实现。
ArrayList:判断包含,以及删除,都是依据元素的equals方法。
HashSet:判断包含,以及删除,都是依据元素的hashCode方法。当hashCode值相同时,再判断一次equals方法。
TreeSet:
TreeSet集合是用于给元素进行排序的。那么自定义元素本身不具备比较性,treeSet集合是无法对元素进行排序的。所以,在自定义对象时,需要对象具备一个扩展功能,用于比较的,而java已经提供了接口,可以让实现它的对系那个具备比较性。
那么自定义类,要想被treeSet排序,就要实现Comparable接口,以具备比较功能。
也可以将一个实现了Comparato接口的子类对象作为参数传递给TreeSet集合的构造函数即可,这样该集合就具备了比较功能。
TreeSet排序方式有两种:
1,让元素自身具备比较性
其实是让元素实现Comparable接口,覆盖CompareTo方法。这称为元素的自然排序。
2,当元素自身不具备比较性,或者元素具备的比较性不是所需要的,定义一个比较器。
其实就是定义一个类,实现Comparator接口,覆盖Compare方法。将comparator接口的子类对象作为参数传递给TreeSet的构造函数。
当元素自身具备比较性,同时TreeSet集合也具备比较器,这时以比较器为主。
所以建议使用第二种方法,比较灵活。
**一般在描述一个对象时,如果该对象封装了具体的数据,会出现很多这样的对象,这时就需要进行容器的存储。
那么描述该类对象时,一般要复写几个方法:
1,hashCode()
2,equals()
3,toString()
4,最好实现Comparable接口让该类具备自然排序功能。
建立对象自身判断是否相同的依据,同时让对象具备基本的比较性。
泛型:
泛型其实就是jdk1.5版本以后出现的一个安全机制。,泛型其实是给编译器使用的。
Al.add(3);//al.add(new Integer(3));因为jdk1.5之后有自动装箱,所以会自动把3装成对象。
集合中存储了不同类型的对象,取出时,容易在运行时时期发生classCastException类型转换异常。为了避免这个问题的发生,如果在存储的时候名气了集合要操作的数据类型,这样取就没有问题了。
就需要在定义集合时,就立刻明确元素的类型。
其实借鉴于数组。
可以通过<>来明确元素的类型。
ArrayList<String> al = new ArrayList<String>();
泛型的好处:
1,将运行时期出现的classCastException问题,转移到编译时期。
2,泛型的出现避免了强制转换的麻烦。
泛型的表现形式是<>;
什么时候使用泛型?
只要用到的类或者接口的旁边有<>的时候,就要明确具体类型。
泛型的使用其实就是给<>传递实际参数,而这个参数就是一个具体的引用数据类型。
什么时候使用泛型类?
当类要操作的引用数据类型不确定的时候,可以使用泛型来定义。
也就是定义一个类型参数。
具体要操作什么类型的对象,有使用该类的使用者来明确,将具体的类型作为实际参数传递给<>;
Class Tool<Q>
{
Private Q obj;
Public void setObj(Q obj){
This.obj = obj;
}
Public Q getObj(){
Return obj;
}
}
当泛型定义在类上,该泛型作用于整个类。当该建立对象时,就明确了具体类型。那么凡是使用了类上定义的泛型的方法,操作的类也就固定了。
当希望类中的方法,可以操作任意类型而不受类中泛型限制。
可以将泛型定义在方法上。泛型方法。
Public <Q> void print(Q q){
System.out.println(“print”+q);
}
当类中定义static方法时,静态方法是不可以直接访问类上的泛型。因为类上的泛型只有通过建立对象才能明确具体类型。
所以静态方法如果操作的引用数据类型不确定,只能将泛型定义在方法上。
(静态方法上定义泛型,必须定义在static关键字之后)
Public static<W> void method(W w){
System.out.prinln(method+”w”);
}
当方法中操作的应用数据类型不确定,而且和对应的对象执行的类型也不一定一致。
这时就将泛型定义在方法上。
泛型接口:
1,
Class InterImpl implements Inter<String>{
Public void show(String s){
System.out.println(s);
}
}
2,
Class InterImpl<T> implements Inter<T>{
Public void show(T t){
System.out.println(“show”+t);
}
}
泛型:通配符?代表任意类型。
Public static void show(Collection<?> coll){
Iterator<?> it = coll.iterator();
While(it.hasNext()){
System.out.println(it.next());
}
}
定义集合时要保证左右两边的类型一致。两边只有一边定义泛型,也是可以支持,至少新老版本兼容,但是一样会出现提示信息。
泛型限定:
定义T只能固定一种类型,定义?可以是任意类型,只想操作该类或该类的子类。要使用泛型限定。
? extends E:接收E类型或者E的子类型。
? super E:接收E类型或者E类型的父类型。
例如:
Public static void show(Collection<? extends Person> coll){
Iterator<? extends Person> it = coll.itrator();
While(it.hasNext()){
System.out.println(it.next());
}
}
集合框架中的另一个顶层接口:Map
Map集合的特点:
1,是一个双列集合,collection是单例集合
2,Map一次存一对元素,同时键值对的形式。建和值有对应关系,collection是一次存一个元素。
3,Map集合必须保证集合中键的唯一性。
Map集合中常见的功能:
1,添加
v put(k , v);将k和v作为元素存储如map集合,当存入相同的k时,
新的值会覆盖原来的值,并返回原来的值。
void putAll(map);
2,删除
Clear();
V remove(k):按照键删除,并返回被删除的键对应的值。
3,判断
Boolean containsKey(Object key)
Boolean containsValue(Object value);
Boolean isEmpty();
4,获取
Int size();获取map集合的元素个数
V get(k);通过键获取值。
Collection values();获取map集合中所有的值。
Set keySet():获取map集合中所有的键。
Set entrySet():获取的是键值的映射关系,将映射关系存入到set集合中。
Map集合没有迭代器。迭代器是collection集合具备的,Map集合的取出元素的原理就是将map集合先转成set集合,然后再进行迭代。
Map
|--Hashtable:底层是哈希表数据结构(同步的,不允许null作为键,null作为值)
|--properties:用于配置文件的定义和操作,使用频率非常高,同时键和值都是字符串。是集合中可以和IO技术相结合的对象。
|--HashMap:底层是哈希表数据结构(不同步的,允许null作为键,允许null作为值)
|--LinkedHashMap:可以保证hashMap存入顺序和取出顺序一致
|--TreeMap:可以用来对map集合中的键进行排序。
如何获取集合中的所有元素?
一:
1,获取所有的键,再通过对所有的键进行遍历,在遍历中通过get方法获取每一个键的对应的值,使用keySet方法获取map集合中键的集合。
2,对set集合进行迭代器的操作。
Set<Integer> keySet = hm.keySet();
Iteraror it = keySet.itertor();
While(it.hasNext()){
Integer i = it.next();
String s = hm.get(i);
System.out.println(s+”...”+i);
}
二:
1,将map集合中的键值关系取出,并封装成一个键值关系对象,再存储到一个set集合中。
键值映射关系封装对象后的数据类型是map.entry(内部接口)
Entry就是一个map接口中的内部静态接口。
作为一个键值关系的数据类型存在。
使用entrySet获取map集合中的所有键值。
Set<Map.Entry<Integer,String>> entry = hm.entrySet();
Iterator<Map.Enrty<Integer,String>> it = entrySet.iterator();
While(it.hasNext()){
Map.Entry<Integer,String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+”...”+value);
}
hashMap:参考HashSet
存入的对象是无序的,想要保证有序。可以使用子类LinkedHashmap。存入和取出的顺序是一致的。
TreeMap:参考TreeSet
Utility:集合中的工具类:
如果有一堆元素。
要是元素重复,选择ArrayList集合,但是想要让元素按顺序排序,可以使用集合中的工具类。
工具类有两种。collections,Arrays
这两个工具类的特点:类中的方法都是静态的,不需要创建对象。
1,collections
Collections是集合对象的工具类,提供了操作集合的工具方法。
Fill(al,”kk”);将集合中的元素替换成指定的元素kk。
Reverse(al);集合元素反转,头尾对调
Swap(al,2,4);对集合中的元素进行位置的置换
Shuffle(al);对集合中的元素进行随机的位置置换
toArray();将集合变成数组
给toArray方法传递一个指定类型的数组。
当指定的长度小于集合的长度,该方法会自动创一个该类型的新数组长度和集合长度一致。用于存储集合中的元素,如果指定的数组长度大于集合的长度,那么该方法就不会创建新数组,而是使用传递进来的数组,存储完集合的元素后,其他的未存储的位置为null。
将集合变成数组后,限定了对元素的增删操作。
Xxx synchronizedList(xxx);可以将一个不同步的集合转成一个同步的list集合
2,Arrays
Arrays:是数组的工具类,提供了堆数组的工具方法。
asList(arr);将数组变成集合。
当数组变成集合后,就可以使用集合的方法来操作数组,而不用自己再定义指针进行数组的操作。(有些方法不可以用,只要是改变集合长度的方法都不能用,因为数组是固定长度的)
当数组中的元素时引用数据类型时,变成集合后,就将数组中的元素作为集合中的元素存在,当数组中的元素时基本数据类型时,变成集合后,会将这个数组变成集合中的元素。
List<int[]> list = Arrays.asList(arr);
System.out.println(list);
发表评论
-
javaIO包
2014-02-26 14:30 810Java IO流: 流是一组有 ... -
java多线程
2014-02-26 14:29 898Java多线程: 什么是进程?{ 当前正在运行的程序。 代表 ... -
java包
2014-01-26 17:59 745Java包:(package) 1.对 ... -
java内部类
2014-01-26 17:58 675Java内部类: 内部类:内置类,嵌套类。 将类定义在另一 ... -
java语法
2014-01-26 17:57 6581.java类命名规则? java中的关键字不能够作为类名, ... -
java异常
2014-01-26 17:55 780Java异常 什么是异常? ... -
java面向对象
2014-01-19 20:24 668什么是面向对象? 面向 ... -
java数组
2014-01-19 20:22 672什么是数组? 就是同一种类型数据的集合,其实就是 一个容器。 ... -
java中的运算符
2014-01-19 20:14 538Java运算符? Java中进行运算时所需要运用到的一些符号。 ... -
java中的流程控制
2014-01-19 20:12 726Java中有四类流程控制 判断结构 选择结构 循环结构 顺序结 ... -
java应用程序与数据库的连接
2013-05-30 02:31 783java应用程序与数据库的连接 Java数据库连接,(Jav ... -
java网络编程
2013-05-29 17:07 663java网络编程如果在一台机器上可以用到一个回文地址做测试,1 ... -
java图的邻接矩阵的表示和实现
2013-05-22 21:32 3938邻接矩阵表示的带权图。。。 首先创建了一个带权值的边类,在图中 ... -
线程通讯问题
2013-05-15 17:01 675//有一个数据存储空间,划分为两部分,一部分用于存储人的姓 ... -
java线程锁定当前对象
2013-05-12 15:44 719java实现线程同步,如果有多个线程同时进行,那么程序很有可能 ... -
关于127.0.0.1 IP地址
2013-04-11 11:32 1477回送地址:127.0.0.1。一般用于测试使用。例如:ping ...
相关推荐
Java集合框架是Java编程语言中的一个核心部分,它为数据存储和管理提供了高效且灵活的解决方案。本思维导图及总结旨在深入理解并掌握Java集合的相关概念和使用方法。 首先,我们来了解一下Java集合框架的基本构成。...
本文将深入探讨Java集合框架的基础知识,包括接口、类、以及它们在实际开发中的应用。 首先,Java集合框架由一系列接口和实现这些接口的类组成。主要的接口有`List`、`Set`和`Queue`,它们各自代表了不同特性的数据...
在这个“java集合练习题”中,我们主要关注如何使用Java集合框架来处理数据,特别是对于学生信息的存储、排序和输出。以下是对这个练习题的详细解析: 1. **集合框架简介**: Java集合框架是Java API的一部分,它...
Java集合框架是Java编程语言中不可或缺的一部分,它提供了一组高效的数据结构和算法,使得开发者可以方便地存储和管理对象。这份"Java集合思维导图.xmind.zip"压缩包文件,显然旨在帮助学习者深入理解Java集合框架的...
### Java集合知识大全 #### 一、集合概述 在Java编程语言中,集合是一组用于存储其他对象的对象。集合框架提供了多种数据结构,用于管理不同类型的数据。这些数据结构包括列表(List)、集(Set)、映射(Map)等,每种...
xmind格式的Java集合框架学习导图,包括Collection接口/Map接口以及具体实现类。 同样包含大厂面试题,也在导图中有所体现。 能学到什么: 更加成体系的知识框架,更加全面的、系统的知识。 思维导图: 思维导图具有...
Java集合框架是Java编程语言中的一个核心组成部分,它为数据存储和操作提供了丰富的接口和类。在本篇中,我们将深入探讨Java集合的排序机制以及集合类的详细使用。 首先,我们来了解一下Java集合的基本分类。Java...
Java集合框架中的`List`接口和数组(Array)是两种常用的数据结构,它们在处理数据时各有优势。下面我们将深入探讨如何在Java中实现集合的分组与排序。 1. **集合分组**: 集合分组通常涉及到`GroupingBy`操作,这...
Java集合框架是Java编程语言中用于存储和管理对象的核心组件,它包括了各种接口和类,为处理数据提供了丰富的选择。在本次实验中,我们深入学习了Java集合框架中的两个主要部分:List接口和Map接口,以及它们的主要...
【Java集合】 Java集合框架是Java编程语言中用于存储和操作对象的工具,它提供了多种数据结构,如列表、集、映射等,以适应不同的数据处理需求。集合类通常位于`java.util`包下,是Java程序员必备的知识点。 1. **...
### Java集合框架总结 #### 一、Java集合框架概述 Java集合框架是Java标准库的一部分,它提供了一系列的接口和类来存储和操作各种类型的对象集合。这些接口和类遵循一致的设计模式,使得开发人员可以方便地管理和...
Java 集合类详解 Java 集合类是 Java 语言中的一种基本数据结构,用于存储和操作大量数据。集合类可以分为三大类:Collection、List 和 Set。 Collection 是集合框架中的根接口,提供了基本的集合操作,如 add、...
Java集合框架是Java编程语言中一个非常重要的组成部分,它提供了一组高级的数据结构,使得开发者能够更方便地管理和操作对象。在本次实验中,我们主要关注了三个主要的集合接口:Set、List和Map,以及它们的一些常见...
Java集合框架是Java编程语言中一个非常重要的组成部分,它为开发者提供了存储和操作对象的统一接口和类。这个框架使得处理各种数据结构变得更加方便和高效。在这个“java集合框架的使用”主题中,我们将深入探讨如何...
Java集合框架是Java编程语言中不可或缺的一部分,它提供了一组接口和类,用于高效地存储、管理和操作数据。这个“一个讲解很清晰的Java集合框架PPT”显然是一个对外公开的教育资源,旨在帮助学习者深入理解Java集合...
Java集合框架是Java编程语言中的核心部分,它提供了一种高效、灵活的方式来组织和操作对象的集合。在Java中,集合主要分为两大类:Collection和Map。本文将深入讲解Java集合类,特别是Collection接口和其下的List、...
Java集合整体讲解,其中包含了Collection,Map,Iterator和一些工具类,以及集合整体大框架
Java集合框架是Java编程语言中的核心组件之一,它为存储、管理和操作对象提供了一套高效且灵活的工具。本系列深入讲解了Java集合框架中的重要组成部分,包括HashMap、ArrayList、LinkedHashMap、HashSet以及...
该文档主要详细总结了Java集合的相关知识,包括Collection和Map接口、Collection接口的子接口List和Set接口以及具体的实现类、存储原理等;Map接口的子接口HashMap、LinkedHashMap、TreeMap、Properties等