【移动应用开发技术】黑马程序员-集合篇_第1页
【移动应用开发技术】黑马程序员-集合篇_第2页
【移动应用开发技术】黑马程序员-集合篇_第3页
【移动应用开发技术】黑马程序员-集合篇_第4页
【移动应用开发技术】黑马程序员-集合篇_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】黑马程序员——集合篇

android培训、java培训、期待与您交流!1、集合类为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。集合类的特点

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。2、集合框架的构成及分类3、Collection接口:

常用方法:

1,添加:

add(object):添加一个元素

addAll(Collection):添加一个集合中的所有元素。

2,删除:

clear():将集合中的元素全删除,清空集合。

remove(obj):删除集合中指定的对象。注意:删除成功,集合的长度会改变。removeAll(collection):删除部分元素。部分元素和传入Collection一致。

3,判断:

booleancontains(obj):集合中是否包含指定元素。

booleancontainsAll(Collection):集合中是否包含指定的多个元素。booleanisEmpty():集合中是否有元素。

4,获取:

intsize():集合中有几个元素。

5,取交集:

boolean

retainAll(Collection):对当前集合中保留和指定集合中的相同的元素。如果两个集合元素相同,返回flase;如果retainAll修改了当前集合,返回true。

6,获取集合中所有元素:

Iterator

iterator():迭代器

7,将集合变成数组:

toArray();4、List接口:元素是有序的,元素可以重复。因为该集合体系有索引。常用子类:

ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。练习:importjava.util.*;

importjava.lang.*;

/*

将自定义对象作为元素存到ArrayList集合中,并去除重复元素。

比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。

思路:

1,对人描述,将数据封装进人对象。

2,定义容器,将人存入。

3,取出。

List判断元素是否相同,依据的是元素的equals方法。

*/

classPerson

{

privateStringname;

privateintage;

Person(Stringname,intage)

{

=name;

this.age=age;

}

publicbooleanequals(Objectobj)

{

if(!(objinstanceofPerson))

thrownewRuntimeException("类型不匹配");

Personp=(Person)obj;

System.out.println(+"===="+);

return.equals()&&this.age==p.age;

}

publicStringgetName()

{

returnname;

}

publicintgetAge()

{

returnage;

}

}

classArrayListTest2

{

publicstaticvoidsop(Objectobj)

{

System.out.println(obj);

}

publicstaticvoidmain(String[]args)

{

ArrayListal=newArrayList();

al.add(newPerson("zhangsan",34));

al.add(newPerson("zhangsan",34));

al.add(newPerson("lisi",32));

al.add(newPerson("wangwu",24));

al.add(newPerson("wangwu",24));

al.add(newPerson("zhaoliu",23));

al=singleElement(al);

for(Iteratorit=al.iterator();it.hasNext();)

{

Personp=(Person)it.next();

sop(p.getName()+","+p.getAge());

}

}

publicstaticArrayListsingleElement(ArrayListal)

{

//定义一个临时容器。

ArrayListnewAl=newArrayList();

Iteratorit=al.iterator();

while(it.hasNext())

{

Objectobj=it.next();

if(!newAl.contains(obj))//调用底层方法调用的是equals方法。所以需要复写equals方法。

newAl.add(obj);

}

returnnewAl;

}

}

LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。不同步。相关练习:/*

使用LinkedList模拟一个堆栈或者队列数据结构。

堆栈:先进后出。如同一个杯子。

队列:先进先出。FirstinFirstoutFIFO如同一个水管。

*/

importjava.util.*;

classDuiLie

{

privateLinkedListlink;

DuiLie()

{

link=newLinkedList();

}

publicvoidmyAdd(Objectobj)

{

link.addFirst(obj);

}

publicvoidmyget()

{

returnlink.removeLast();

}

publicbooleanisNull()

{

returnlink.isEmpty();

}

}

Vector:底层是数组数据结构。线程同步。被ArrayList替代了。相关练习:importjava.util.*;

/*

枚举就是Vector特有的取出方式。

发现枚举和迭代器很像。

其实枚举和迭代时一样的。

为什么要设置枚举?

因为枚举的名称以及方法的名称都过长。

所以都被迭代器取代了。

枚举郁郁而终。

*/

classVectorDemo

{

publicstaticvoidmain(String[]args)

{

Vectorv=newVector();

v.add("java01");

v.add("java02");

v.add("java03");

v.add("java04");

Enumerationen=v.elements();

while(en.hasMoreElements())

{

System.out.println(en.nextElement());

}

}

}特有方法:增:add(index,element);在addAll(index,Collection):删:remove(index);改:set(index,element);查:get(index);subList(form,to);listIterator();

List集合特有的迭代器。ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法时有限的。只能对元素进行判断,取出,删除的操作。如果要其他操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的ListIterator方法获取。5、Set:元素是无序的,元素不可以重复。|--HashSet:底层数据结构是哈希表。线程非同步的。HashSet是如何保证元素的唯一性的呢?是通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。

注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。练习:/*

往HashSet集合中存入自定义对象。

姓名和年龄视为同一人。重复元素。

*/

importjava.util.*;

classHashSetTest

{

publicstaticvoidsop(Objectobj)

{

System.out.println(obj);

}

publicstaticvoidmain(String[]args)

{

HashSeths=newHashSet();

hs.add(newPerson("a1",11));

hs.add(newPerson("a1",11));

hs.add(newPerson("a2",13));

hs.add(newPerson("a3",15));

//hs.add(newPerson("a4",17));

sop("a1"+hs.contains(newPerson("a2",13)));

sop("a1"+hs.remove(newPerson("a3",15)));

for(Iteratorit=hs.iterator();it.hasNext();)

{

Personp=(Person)it.next();

sop(p.getName()+","+p.getAge());

}

}

}

classPerson

{

privateStringname;

privateintage;

Person(Stringname,intage)

{

=name;

this.age=age;

}

publicinthashCode()

{

returnname.hashCode()+age;

}

publicbooleanequals(Objectobj)

{

if(!(objinstanceofPerson))

thrownewRuntimeException("数据异常");

Personp=(Person)obj;

return.equals()&&this.age==p.age;

}

publicStringgetName()

{

returnname;

}

publicintgetAge()

{

returnage;

}

}|--TreeSet:可以对Set集合中的元素进行排序。记住:排序时,当注意条件相同时,一定要判断一下次要条件。

因为底层数据结构是二叉树,保证元素唯一性的依据:compareTo方法return0;

TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。TreeSet的第二种排序方式。当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合初始化时,就具备比较性。练习:/*

练习:按照字符串长度排序。

字符串本身具备比较性,但是它的比较方式不是所需要的。

*/

importjava.util.*;

classTreeSetTest

{

publicstaticvoidmain(String[]args)

{

TreeSetts=newTreeSet(newStrLenCompare());

/*匿名内部类。

TreeSetts=newTreeSet(newComparator(){

publicintcompare(Objecto1,Objecto2)

{

if(!(o1instanceofString&&o2instanceofString))

thrownewRuntimeException("类型不匹配");

Strings1=(String)o1;

Strings2=(String)o2;

intnum=newInteger(s1.length()).compareTo(newInteger(s2.length()));

if(num==0)

returnpareTo(s2);

returnnum;

}

});

*/

ts.add("abcd");

ts.add("cc");

ts.add("cba");

ts.add("aaa");

ts.add("z");

ts.add("hahaha");

for(Iteratorit=ts.iterator();it.hasNext();)

{

System.out.println(it.next());

}

}

}

classStrLenCompareimplementsComparator

{

publicintcompare(Objecto1,Objecto2)

{

if(!(o1instanceofString&&o2instanceofString))

thrownewRuntimeException("类型不匹配");

Strings1=(String)o1;

Strings2=(String)o2;

intnum=newInteger(s1.length()).compareTo(newInteger(s2.length()));

if(num==0)

returnpareTo(s2);

returnnum;

}

}5、Map集合:

Map集合:该集合存储键值对。是一对一对往里村,要保证键的唯一性。1,添加。Vput(Kkey,Vvalue)voidputAll(Map<?extendsK,?extendsV>m)

2,删除。voidclear();Vremove(Objectkey)3,判断。booleancontainsKey(Objectkey)booleancontainsValue(Objectvalue)booleanisEmpty()

4,获取。Vget(Objectkey)

intsize()

Collection<V>values()

5、重点:

Set<Map.Entry<K,V>>entrySet()Set<K>keySet()

常用Map子类:|--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合时线程同步的。JDK1.0,效率低|--hashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2效率高。|--TreeMap:底层是二叉树数据结构,线程不同步。可以用于给map集合中的键进行排序。

Map和Set很像。

其实Set底层就是使用了Map集合。

map集合的两种取出方式。

1,Set<Map.Entry<k,v>>entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是Map.Entry。

2,Set<K>keySet:将map中所有的键存入到Set集合,因为Set集合具备迭代器。所以可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。Map集合的取出原理:将map集合转成set集合,在通过迭代器取出。例子:importjava.util.*;

classMapDemo2

{

publicstaticvoidmain(String[]args)

{

Map<String,String>map=newHashMap<String,String>();

map.put("02","zhangsan02");

map.put("05","zhangsan05");

map.put("03","zhangsan03");

map.put("01","zhangsan01");

//将Map集合中的映射关系取出。存入到Set集合中。

Set<Map.Entry<String,String>>entrySet=map.entrySet();

for(Iterator<Map.Entry<String,String>>it=entrySet.iterator();it.hasNext();)

{

Map.Entry<String,String>me=it.next();

Stringkey=me.getKey();

Stringvalue=me.getValue();

System.out.println("key:"+key+"=value:"+value);

}

/*

//先获取map集合的所有键的set集合,keySet();

Set<String>keySet=map.keySet();

//有了Set集合,就可以获取其迭代器。

Iterator<String>it=keySet.iterator();

while(it.hasNext())

{

Stringkey=it.next();

//有了键就可以通过map集合的get方法获取其对应的值。

Stringvalue=map.get(key);

System.out.println("key:"+key+"=value:"+value);

}

*/

}

}

/*

Map.Entry其实Entry也是一个接口,它是Map接口中的一个内部接口。

*/

interfaceMap

{

publicstaticinterfaceEntry

{

publicabstractobjectgetKey();

publicabstractobjectgetValue();

}

}6、常用工具类Collections:它的出现给集合操作提供了更多的功能。这个类不需要创建对象,内部提供的都是静态方法。

静态方法:

Collections.sort(list);//list集合进行元素的自然顺序排序。

Collections.sort(list,newComparatorByLen());///按指定的比较器方法排序。

classComparatorByLenimplementsComparator<String>{

publicintcompare(Strings1,Strings2){

inttemp=s1.length()-s2.length();

returntemp==0?pareTo(s2):temp;

}

}

Collections.max(list);//返回list中字典顺序最大的元素。

intindex=Collections.binarySearch(list,"zz");//二分查找,返回角标。

Collections.reverseOrder();//逆向反转排序。

Collections.shuffle(list);//随机对list中的元素进行位置的置换。

将非同步集合转成同步集合的方法:

Collections中的XXXsynchronizedXXX(XXX);

ListsynchronizedList(list);

MapsynchronizedMap(map);

原理:定义一个类,将集合所有的方法加同一把锁后返回。Collection和Collections的区别:

Collections是个java.util下的类,是针对集合类的一个工具类,提供一系列静态方法,实现对集合的查找、排序、替换、线程安全化(将非同步的集合转换成同步的)等操作。

Collection是个java.util下的接口,它是各种集合结构的父接口,继承于它的接口主要有Set和List,提供了关于集合的一些操作,如插入、删除、判断一个元素是否其成员、遍历等。Arrays:用于操作数组对象的工具类,里面都是静态方法。

asList方法:将数组转换成list集合。

String[]arr={"abc","kk","qq"}

List<String>list=Arrays.asList(arr);//将arr数组转成list集合。

将数组转换成集合,有什么好处呢?用aslist方法,将数组变成集合;

可以通过list集合中的方法来操作数组中的元素:isEmpty()、contains、indexOf、set;

注意(局限性):数组是固定长度,不可以使用集合对象增加或者删除等,会改变数组长度的功能方法。比如add、remove、clear。(会报不支持操作异常UnsupportedOperationException);

如果数组中存储的引用数据类型,直接作为集合的元素可以直接用集合方法操作。

如果数组中存储的是基本数据类型,asList会将数组实体作为集合元素存在。

集合变数组:用的是Collection接口中的方法:toArray();

如果给toArray传递的指定类型的数据长度小于了集合的size,那么toArray方法,会自定再创建一个该类型的数据,长度为集合的size。

如果传递的指定的类型的数组的长度大于了集合的size,那么toArray方法,就不会创建新数组,直接使用该数组即可,并将集合中的元素存储到数组中,其他为存储元素的位置默认值null。

所以,在传递指定类型数组时,最好的方式就是指定的长度和size相等的数组。

将集合变成数组后有什么好处?限定了对集合中的元素进行增删操作,只要获取这些元素即可。System类:

描述系统一些信息。

获取系统属性信息:PropertiesgetProgerties();

out:标准输出:默认是控制台。

in:标准输入,默认是键盘。

importjava.util.*;

classSystemDemo

{

publicstaticvoidmain(String[]args)

{

Propertiesprop=System.getProperties();

//因为Properties是Hashtable子类,也就是Map集合的一个子类对象。

//那么可以通过map的方法取出该集合中的元素。

//该集合中存储的都是字符串,没有泛型定义。

//如何在系统中自定义一些特有信息呢?

System.setProperty("mykey","myvalue");

//获取指定属性信息。

Stringvalue=System.getProperty("");

System.out.println("value="+value);

//可不可以在jvm启动时,动态加载一些属性信息呢?

//-D<name>=<value>

Stringv=System.getProperty("hah");

System.out.println("v="+v);

/*

for(Objectobj:prop.keySet())

{

Stringvalue=(String)prop.get(obj);

System.out.println(obj+"="+value);

}

*/

}

}Runtim对象

该类并没有提供构造函数。

说明不可以new对象。那么会直接想到该类的方法都是静态的。

发现该类中还有非静态方法。

说明该类肯定会提供了方法获取本类对象,而且该方法是静态的。并且返回值类型是本类类型。

由这个特点可以看出该类使用了单例设计模式完成。

该方法是staticRuntimegetRuntime();

*/

classRuntimeDemo

{

publicstaticvoidmain(String[]args)throwsException

{

Runtimer=Runtime.getRuntime();

Processp

=r.exec("notepad.exeSystemDemo.java");//\为转义字符,所以应写为\\

//p.destroy();

}

}Date对象

可以对时间的进行操作的对象。

importjava.util.*;

importjava.text.*;

classDateDemo

{

publicstaticvoidmain(String[]args)

{

Dated=newDate();

System.out.println(d);

//将模式封装到SimpleDateFormat对象中。

SimpleDateFormatsdf=newSimpleDateFormat("yyyy年MM月dd日Ekk:mm:ss");

//调用format方法,让模式格式化指定Date对象。

System.out.println(sdf.format(d));

}

}Calendar对象

importjava.util.*;

importjava.text.*;

classCalendarDemo

{

publicstaticvoidmain(String[]args)

{

Calendarc=Calendar.getInstance();

String[]month={"一月","二月","三月","四月"

,"五月","六月","七月","八月"

,"九月","十月","十一月","十二月"};

String[]week={"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

intindex=c.get(Calendar.MONTH);

intindex1=c.get(Calendar.DAY_OF_WEEK);

sop(c.get(Calendar.YEAR)+"年");

//sop(c.get((Calendar.MONTH)+1)+"月");

sop(month[index]);

sop(c.get(Calendar.DAY_OF_MONTH)+"日");

sop((c.get(Calendar.DAY_OF_WEEK)));

sop(week[index1]);

/*

Dated=newDate();

SimpleDateFormatsdf=newSimpleDateFormat("yyyy");

sdf.format(d)

System.out.println(d);

*/

}

publicstaticvoidsop(Objectobj)

{

System.out.println(obj);

}

}

泛型(Generic)

泛型:JDK1.5版本以后出现的新特性。用于解决安全问题。是一个安全机制。

好处:

1,将运行时期出现的问题ClassCastException,转移到了编译时期。

方便于程序员解决问题,让运行时期问题减少,安全。

2,避免了强制转换的麻烦。

泛型格式:通过<>来定义要操作的引用数据类型。

在使用java提供的对象时,什么时候写泛型呢?

通常在集合框架中很常见。

只要见到<>就要定义泛型。

其实<>就是用了接受类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>即可。classGenericDemo

{

publicstaticvoidmain(String[]args)

{

ArrayList<String>al=newArrayList<String>();

al.add("abc01");

al.add("abc02");

al.add("abc0991");

al.add("abc014");

//al.add(4);

for(Iterator<String>it=al.iterator();it.hasNext();)

{

Strings=it.next();

System.out.println(s+":"+s.length());

}

}

}泛型的使用

1、泛型类

在类声明时通过一个标识符表示类中某个字段的类型或者某个方法的返回值或参数的类型,这样在类声明或实例化的时候只要指定自己需要的类型就ok。

声明带泛型的类:

class类名<泛型类型1,泛型类型2……>{

泛型类型

变量名;

泛型类型

方法名(){}

返回值类型方法名(泛型类型变量名){}

}

使用带泛型的类:

类名<具体类>对象名=new类名<具体类>();

类型参数规范:推荐使用规范-常见的泛型,泛型只保存在源文件中,class文件中不存在;也就是说在编译阶段就会丢失,基本数据类型不能作为泛型类型;

K键,比如映射的键

key的类型

V值,比如Map的值value类型

E元素,比如Set<E>

Element表示元素,元素的类型

T泛型,Type的意思

泛型好处:限定添加类型和消除强转转换的麻烦!

练习例子需求:设计一个表示点的类Point,该类有两个字段,一个是横坐标x,一个纵坐标y,要求坐标有3种表达形式(Integer,Double,String):如果不使用泛型的话可以新建多个类,但是内部方法体只有参数类型不一样,所以用泛型的话更加简单,给定一个占位符,并不明确表示到底是什么类型,在实际运用的时候才确定类型!!很好的例子!packagegeneric;classPoint<T>{privateTt1;privateTt2;publicTgetT1(){returnt1;}publicvoidsetT1(Tt1){this.t1=t1;}publicTgetT2(){returnt2;}publicvoidsetT2(Tt2){this.t2=t2;}}publicclassGenericDemo{publicstaticvoidmain(String[]args){//String类型的Point<String>p=newPoint<String>();p.setT1("2");p.setT2("3");System.out.println(p.getT1());System.out.println(p.getT2());//Integer类型的Point<Integer>p2=newPoint<Integer>();p2.setT1(23);p2.setT2(24);System.out.println(p2.getT1());System.out.println(p2.getT2());//Double类型的Point<Double>p3=newPoint<Double>();p3.setT1(23.00);p3.setT2(24.00);System.out.println(p3.getT1());System.out.println(p3.getT2());Set<String>s=newHashSet<String>();//创建一个容器对象,应该在创建的时候就明确是装什么的s.add("a");//s.add(1);//此时就加不进去了,因为已经限制了容器内参数类型!//此时就能保证集合里元素类型一致,Set<Integer>treeSet=new

TreeSet<Integer>();//规定key只能是String,value是DateMap<String,Date>map=newHashMap<String,Date>();//Vput(Kkey,Vvalue)Datev=map.put("",newDate());//和上面定义的类型一样//Vget(Objectkey)

Dateval=map.get("");}}运行结果23232423.024.0这样的话借助泛型一个类就可以表达多个不同类型的参数!要求消除强制类型的转换,如,使用Comparable比较时每次都需要类型强转;1、没有加上泛型,最初的需要强制类型转换packagegeneric;importjava.util.Set;importjava.util.TreeSet;classPersonimplementsComparable{//需要进行排序的类要实现ComparableprivateIntegerage;publicPerson(Integerage){super();this.age=age;}@OverridepublicintcompareTo(Objecto){Personp=(Person)o;//强制类型转换returnpareTo(p.age);}publicStringtoString(){returnthis.age.toString();}}publicclassGenericDemo2{publicstaticvoidmain(String[]args){Setset=newTreeSet();set.add(newPerson(15));set.add(newPerson(12));set.add(newPerson(19));set.add(newPerson(53));set.add(newPerson(62));System.out.println(set);}}第二步:加上泛型,不再需要强转(因为类型已经固定了)!packagegeneric;importjava.util.Set;importjava.util.TreeSet;classPersonimplementsComparable<Person>{//privateIntegerage;publicPerson(Integerage){super();this.age=age;}@OverridepublicintcompareTo(Persono){returnpareTo(o.age);//排序}publicStringtoString(){returnthis.age.toString();}}publicclassGenericDemo2{publicstaticvoidmain(String[]args){Set<Person>set=newTreeSet<Person>();set.add(newPerson(15));set.add(newPerson(12));set.add(newPerson(19));set.add(newPerson(53));set.add(newPerson(62));System.out.println(set);}}2、声明多个泛型类型和通配符若一个类中多个字段需要不同的泛型声明,则在声明类的时候指定多个泛型类型即可;格式:publicinterfaceIDAO<PK,T>{PKadd(Tt);voidremove(PKid);voidupdate(PKid,Tt);Tget(PKid);}在进行引用传递的时候泛型类型必须匹配才可以传递,否则编译不通过;使用?,表示未知类型的泛型对象:Li

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论