集合
Collection接口:单列接口,用来存储一个一个的对象
List接口:存储有序的,可重复的数据(ArrayList,LinkedList,Vector)
Set接口:存储无序的,不可重复的数据(HashSet,LinkedHashSet,TreeSet)
Map接口:双列集合,用来存储一对(key-value)的数据(HashMap,LinkedHashMap,TreeMap,HashTable,ProperTies)
1.Collection接口:
容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。
package cz.oneday.gather;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class CollectionTest {
@Test
public void test(){
Collection coll =new ArrayList();
coll.add(123);
coll.add(456);
coll.add(789);
coll.add(new String("cz"));
coll.add(false);
System.out.println(coll);
boolean contains=coll.contains(789);
System.out.println(contains);
System.out.println(coll.contains(new String("cz")));
//删除一个
coll.remove(123);
System.out.println(coll);
//删除多个
Collection coll1= Arrays.asList(123,456);
coll.removeAll(coll1);
System.out.println(coll);
//删除公共的
Collection coll2=Arrays.asList(123,456,789,9);
coll.retainAll(coll2);
System.out.println(coll);
//是否相等
System.out.println(coll.equals(coll1));
//计算哈希值
System.out.println(coll.hashCode());
//集合-》数组
Object[] a=coll.toArray();
for (int i=0;i<a.length;i++){
System.out.println(a[i]);
}
//数组转化为集合
List<String> list= Arrays.asList(new String[]{"tmd","rcz","qs"});
System.out.println(list);
List c=Arrays.asList(123,456,789);
System.out.println(c);
//遍历集合
//iterator()
}
}
2.Set接口:
package cz.oneday.gather;
/**
*set接口:存储无序的、不可重复的数据
* 1.HashSet:作为set接口的主要实现类;线程不安全;可以存储null值
* 2.LikedHashSet:作为HahSet的子类;遍历其内部类数据时,可以按照添加的顺序遍历。
* 3.TreeSet:可以按照添加对象的指定属性,进行排序。
*/
import cz.oneday.cz.User;
import org.junit.Test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 1.Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法
* 2.要求:向Set中添加的数据,其所在的类一定要重写hashCode()和equals()
* 要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码.
*
* */
public class SetTest {
/**
*一、set:存储无序的、不可重复的数据
* 以HashSet
* 1.无序性:不等于随机。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。
* 2.不可重复性:保证添加的元素按照equals()判断时,不能返回true。即:相同的元素只能添加一个。
*
* 二、添加元素的过程:以HashSet为例
* 我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
* 此哈希值接着通过某种算法计算出在Hashset底层数组中存放位置(即为:索引位置),
* 判断数组此位置上是否已经有元素:如果此位置上没有其他元素,则元素a添加成功
* 如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
* 如果Hash值不相同,则元素a添加成功
* 如果hash值相同,进而需要调用元素a所在类的equals()方法:
* equals() 返回true,元素a添加失败
* equals()返回false,则元素a添加成功
* * */
@Test
public void test(){
Set set=new HashSet();
set.add(123);
set.add(123);
set.add(456);
set.add(789);
set.add("CZ");
set.add(new User("cz",12));
set.add(new User("cz",12));
set.add("程泽");
Iterator iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
3.List接口
package cz.oneday.gather;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* List接口:元素有序、且可重复《动态数组》替换原有的数组
* 1.ArrayList:作为List接口的主要实现类,效率高,但线程不安全。底层使用Object[] elementData存储
* 2.LinkedLis:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储。
* 3.Vector:作为List接口的古老实现类,线程安全,但效率低。底层使用Object[] elementData存储
*
* 面试题:ArrayList、LinkedList、Vector三者的异同?
* 相同点:三个类都是实现了List接口,存储数据的特点相同:元素有序、且可重复的数据。
* 不同点:
* ArrayList:作为List接口的主要实现类,效率高,但线程不安全。底层使用Object[] elementData存储
* LinkedLis:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储。
* Vector:作为List接口的古老实现类,线程安全,但效率低。底层使用Object[] elementData存储
*/
public class ListTest {
@Test
public void test(){
ArrayList list=new ArrayList();
list.add(123);
list.add(456);
list.add(789);
list.add("cz");
System.out.println(list);
//指定位置插入
list.add(1,"cz");
System.out.println(list);
//添加所有元素
List<Integer> list1= Arrays.asList(1,2,3);
list.addAll(list1);
System.out.println(list.size());
//获取
System.out.println(list.get(3));
}
@Test
public void test1(){
ArrayList list=new ArrayList();
list.add(123);
list.add(456);
list.add(789);
list.add("cz");
System.out.println(list);
//返回集合上首次出现的位置
int index=list.indexOf("cz");
System.out.println(index);
//返回集合上最后一次出现的位置
int index1=list.lastIndexOf("cz");
System.out.println(index1);
//删除指定元素
Object obj= list.remove(0);
System.out.println(obj);
System.out.println(list);
//x修改
list.set(1,123);
System.out.println(list);
//返回左开右闭区间的值
List sublist=list.subList(0,1);
System.out.println(sublist);
System.out.println(list);
}
/**总结:常用方法
* 增:add(Object obj )
* 删:remove(int index)/remove(Object obj)
* 改:set(int index,Object ele)
* 查:get (int index)
* 插:add(int index,Object ele)
* 长度:size()
* 遍历:1.Iterator迭代器
* 2.增强for循环
* 3.普通循环
*/
@Test
public void test3(){
ArrayList list=new ArrayList();
list.add(123);
list.add(456);
list.add(789);
list.add("cz");
System.out.println(list);
//迭代器
Iterator iterator=list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("****************");
//增加for循环
for (Object obj:list){
System.out.println(obj);
}
System.out.println("****************");
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
4.Map接口:
package cz.oneday.gather;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Map实现类的结构情况:
*
* Map:双列数据,存储Key-value对的数据
* HashMap:作为Map的主要实现类:线程不安全的,效率高;存储Key-value对的数据
* LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
* 原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素。
* 对于频繁的遍历操作,此类执行效率高于HashMap。
* TreeMap:保证按照添加的Key-value对进行排序,实现排序遍历。此时考虑Key的自然排序或定制排序。
* 底层使用红黑树
* Hashtable:作为古老的实现类;线程安全,效率低;不能存储Key-value对的数据
* Properties:常用来处理配置文件,Key-value都是String类型。
*
*
* HashMap的底层:数组+链表(jdk7之前)
* 数组+链表+红黑树(jdk8)
*
* 面试题:
* 1.HashMap的底层实现原理;
* 2.HashMap 和 Hashtable的异同?
* 3.CurrentHashMap 和 Hashtable的异同?
*
* 二、Map结构的理解
* Map中的key:无序的、不可重复的,使用Set存储所以得key ---->key所在的类要重写equals()和hashCode()(以HashMap为例)
* Map中的value:无序的、不可重复,使用Collection存储所有的value --->value所在的类要重写equals()
* 一个键值对:key-value构成了一个Entry对象
* Map中的entry:无序的、不可重复的,使用Set存储所有的entry
*
*
* 三、HashMap的底层实现原理?以jdk1.7为例说明:
*
*
*
*
*
* */
public class MapTest {
@Test
public void test(){
Map map=new HashMap();
map.put(12,"nn");
map.put(34,"mn");
map.put(56,"bz");
map.put(78,"xz");
map.put(91,"cx");
map.put(21,"vz");
System.out.println(map);
//方式一:
Set entrySet=map.entrySet();
Iterator iterator=entrySet.iterator();
while (iterator.hasNext()){
Object obj=iterator.next();
Map.Entry entry=(Map.Entry)obj;
System.out.println(entry.getKey() + "---------------->" + entry.getValue());
}
System.out.println();
//方式二
Set keySet=map.keySet();
Iterator iterator1=keySet.iterator();
while (iterator1.hasNext()){
Object key=iterator1.next();
Object value=map.get(key);
System.out.println(key + "===========" + value);
}
}
}
5.迭代器Iterator
package cz.oneday.gather;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 集合元素的遍历操作,使用迭代器Iterator接口
*1.内部的方法:hasNext()和next()
*2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
*3.内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()
* */
public class IteratorTest {
@Test
public void test() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(789);
coll.add(new String("cz"));
coll.add(false);
Iterator iterator=coll.iterator();
/** 方式一
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
*/
//方式二:不推荐
for (int i=0;i<coll.size();i++){
System.out.println(iterator.next());
}
//推荐 方法
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
@Test
public void test1(){
Collection coll=new ArrayList();
coll.add(123);
coll.add(456);
coll.add(789);
coll.add(new String("cz"));
coll.add(false);
//删除集合中的“cz”
Iterator iterator=coll.iterator();
while (iterator.hasNext()){
Object obj=iterator.next();
if ("cz".equals(obj)){
iterator.remove();
}
}
//遍历集合
iterator = coll.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
5.for加强循环`
package cz.oneday.gather;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
/**
* jdk5.0新增了foreach循环,用于集合遍历、数组
*
* */
public class ForTest {
@Test
public void test(){
Collection coll=new ArrayList();
coll.add(123);
coll.add(456);
coll.add(789);
coll.add(new String("CZ"));
coll.add(false);
//for(集合元素的类型 局部变量:集合对象)
//内部任然调用了迭代器
for (Object cz:coll){
System.out.println(cz);
}
}
@Test
public void test1(){
int[] z=new int[]{1,2,35,4,5,4,66};
//for(数组元素的类型 局部变量:数组对象)
for (int c:z){
System.out.println(c);
}
}
@Test
public void test2(){
String[] cz=new String[]{"A","B","C","D","E","F"};
/**方式一:普通for赋值
for (int i=0;i< cz.length;i++){
cz[i]="CZ";
}
*/
for (String CZ:cz){
CZ="CZ";
}
for (int i=0;i<cz.length;i++){
System.out.println(cz[i]);
}
}
}