黑马程序员_集合

来源:互联网 发布:中国移动m823软件 编辑:程序博客网 时间:2024/06/07 21:45

------- android培训java培训、期待与您交流! ---------- 

集合

 

集合的作用:

用来存放数据,对象。长度可以变化,类型也可变。

 

开始ArrayList的两个小点

一、add方法的参数类型是object。以便与接受任意类型对象。

二、集合中存储的都是对象的引用(地址)。

迭代器:  就是在集合中取出元素的方式(和遍历一样)。因为每一个容器中装的对象,都是需要取出然后           再操作。不仅仅是打印。这个操作只有在上课中用到。一次把每一个元素都打印出来,所以局                  限性很大。

Iterator:是一个接口。三种方法:hasNest();nest();

接口型引用只能指向自己的子类对象。通过集合的方法获取出来。

把取出方式定义在集合的内部,这样去除方式就可以直接访问集合内部的元素。

那么取出方式就被定义成了内部累。

而每一个容器的数据结构不同,所以取出的动作细节也就不一样。但是都有共性内容判断和取出。那么可以将写出性抽取。

那么这些内部累都符合一个规则:该规则是Iterator。如何获取集合的取出对象呢?

通过一个对外提供的方法:Iterator();

毕老师的比喻就是:抓娃娃的夹子,就是迭代器。【夹子很多细节】

 

老外的优化:

For(Iteratorit = al.iterator();it.hasNext();){

Sop(it.next());

}

Collection的简介】

LIST

Collection

|--List:元素是有序的,元素可以重复,因为该集合体系有索引。

|--Set:元素是无序的,元素不可以重复。

List所有的特有方法就是:对角标的使用。

Add(index,element);////(在制定位置添加元素,然后其他的都会往后移动;)

addAll(index,Collection);////

Remove(index);////(删除指定位置的元素;)

Get(index,element);////(改变指定位置上的元素;)

查【重要】

Get(index);////(获取指定位置的元素;)

subList(from,to);////(获取很多元素,开始和结束位置;包头不包尾)(遍历,低效)

迭代器:(使用夹子处理迭代,指针的出现)

【操作角标的都是数组原理】

还有的几个:

indexOf()----获取对象的位置。al.indexOf(“java02”);

listIterator();------列表迭代器。【由于迭代器只有三种方法:hasNext,next,remove。】

在迭代时,不可能通过集合对象的方法操作集合中的元素。

因为会发生ConcurrentModificationExc异常。【集合和迭代都会操作集合中的元素,并发

所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,

只能对元素进行判断,取出,删除的操作。

如果想要其他的操作如:添加,修改等,就需要使用其自接口,ListIterator。

该接口只能通过Lise集合的ListIterator方法获取。

添加:是在制定元素后面添加;

修改:li.set(“..”);在制定位置上换成set中的对象。

例子:

---ListIterator li = al.listIterator();

---Object obj=li.next();

---if(obj.equals(“java002”))-----li.set(“java0006”)[修改]-----li.add(“java0009”)[添加];

只有listIterator具有此特点,因为它有角标。

hasNest,和 hasPrevious,后前。

Next previous分别是返回下一个元素和上一个元素。返回值是对象。

listIterator:对集合遍历过程中的增删该查,就使用这个。

 

List

|-----ArrayList:底层数据结构使用的是数组结构。      特点:查询很快。但是添加删除都是稍慢。        |                                                                                                  线程不同步(1.2版本)

|                           口口口口

|----LinkedList:底层使用的是链表数据结构。             特点:增删很快。但是查询稍慢。

|                           口口口口

|

|-----Vector:底层是数组数据结构。线程同步(1.0版本的,那是框架还没有出现【被替代】作为了解)

 

Vector的特殊:

elements();---->返回此向量的组件的枚举。可以拿到很多的元素。返回值是Enumeration接口...

枚举就是Vector特有的取出方式,(迭代器,遍历,for..)

Enumeration en = v.elements();

While(en.hasMoreElements()){

Sop(en.nextElement());

}

发现枚举和迭代器很像。

其实枚举和迭代是一样的,因为枚举的名称以及方法的名称都很长,所以被迭代器取代了。

枚举就挂了、、优先考虑:Iterator,而不是Enumeration。。。

【io有个对象使用了枚举,所以没有完全   消失】

 

LinkedList

连接列表。

特有方法:

addFirst();----倒序

addLast();-----正序

 

removeFiest();----|

|------获取元素,删除元素。为空抛异常。

removeLast();-----|

可以获取全部元素,便是删取。。。

 

getFirst();--| 

|-----获取元素,不删除元素。为空抛异常。

getLast();---|

【旧版本】

 

JDK1.6出现了替代方法

offerFirst();

offerLast();

peekFirst();

peekLast();

获取元素,不删除元素。为空返回null。

pollFirst();

pollLast();

获取元素,删除元素。为空返回null。

---------------------------------------------------------------------

例子

堆栈:先进后出-->记忆模型:杯子

队列:先进先出-->记忆模型:水管

思维是:封装起来,对外暴露最简单的操作方式。

Class Duilie{

private LinkedList link;

DuiLie(){

Link = new LinkedList();

}

public void myAdd(Object ob){

link.addFirst(obj);

}

publlic Object myGet(){

return link.removeLast();

}

public boolean isNull(){

return link.isEmpty();

}

}class LinkedListTest{

Public static void main(String[] args){

DuiLie di = new DuiLie();

di.myAdd(“java001”);

di.myAdd(“java002”);

di.myAdd(“java003”);

di.myAdd(“java004”);

Sop(di.myGet());

}

【要求:必须会!】

-----------------------------------------------------------------------------

定义功能去除ArrayList中的重复元素。

package cn.itcast.p3.arraylist.test;

import java.util.ArrayList;

import java.util.Iterator;

import cn.itcast.p.bean.Person;

/*

 * 定义功能去除ArrayList中的重复元素。

 */

public class ArrayListTest2 {

         publicstatic void main(String[] args) {  

//                demo();     

//                singleDemo();    

                  ArrayList al = new ArrayList();

                  al.add(newPerson("lisi1",21));

                  al.add(newPerson("lisi2",22));

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

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

                  al.add(newPerson("lisi2",22));

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

                  System.out.println(al);

                  al = getSingleElement(al);

                  System.out.println(al.remove(newPerson("lisi2",22)));

                  System.out.println(al); 

         }

         publicstatic void singleDemo() {

                  ArrayList al = new ArrayList();

                  al.add("abc1");

                  al.add("abc2");

                  al.add("abc2");

                  al.add("abc1");

                  al.add("abc");

                  System.out.println(al);

                  al = getSingleElement(al);

                  System.out.println(al);

         }

         publicstatic ArrayList getSingleElement(ArrayList al) {

                  //1,定义一个临时容器。

                  ArrayList temp = new ArrayList();

                  //2,迭代al集合。

                  Iterator it = al.iterator();

                  while(it.hasNext()){

                           Objectobj = it.next();

                           //3,判断被迭代到的元素是否在临时容器存在。

                           if(!temp.contains(obj)){

                                    temp.add(obj);

                           }

                  }return temp;

         }

 

         publicstatic void demo() {

//                al.add(5);//al.add(new Integer(5));

         }

}------>关于迭代器中写两个next()引发的问题,偶行奇不行

{没学集合之前困扰我很长时间的一个问题}

 

------------------------------------------------------------------------------------------------------

 

List集合判断元素是否相同,依据是元素的equals方法。(contains和remove)

不同数据结构中试用的不同。

重写的equals方法:

<按照名字和年龄一致才删除>

Public boolean equals(Object  obj){

If(!(obj  instanceof Person))

return false;

Person  p = (Person)obj;//强转

System.out.println(this.name+”。。。”+p.name);

returnthis.name.equals(p.name)&&this.age==p.age;//精彩所在

}

 

SET

|---Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。

|----HashSet:底层数据结构是哈希表(里面有顺序,按表里取值,顺序未必和存进去的一致。)

|                           HashSet是如何保证元素唯一性的呢?

是通过两个方法:hashCode和equals来完成。

如果元素的HashCode值相同,才会判断equals是否为true。

如果元素的hashcode值不同,才会调用equals。

【开发一般都复写equalshashcode方法】(容易出现的错误就是复写没有成功。一般编译不会出错。)

注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的                hashcodeequals方法。

|----TreeSet:(特点)可以对Set集合中的元素进行排序。

当使用TreeSet时,使用者(类)需要实现Comparable接口-->重写compareTo      方法。意思就是让该类具有比较性。TreeSet可以识别。{return1,0(默认为相 同对象),-1.}【底层调用,符合要求就行】

底层数据结构是二叉树,保证元素的唯一性的依据就是:compareTo方法return 0

TreeSet的第一种排序方式:

让元素自身具备比较性,元素需要实现comparable接口,覆盖compareTo方法,这种  方式也称为元素的自然顺序,或者叫做默认顺序。

TreeSet的第二种排序方式:【很重要的】

当元素自身不具备比较性时,或者具备的比较性不是所需要的。

这时就需要让集合自身具备比较性。<字符串本身具有比较性>

 

--->在集合初始化时,就有了比较方式。(参阅构造方法)【升级】

定义了比较器,将比较器对象作为参数传给TreeSet集合的构造方法。

当两种排序都存在时,以比较器为主。

定义一个类,实现Comparator接口,覆盖compare方法。

Set集合的功能和Collection是一致的。

位置一样之后,还可以在此判断元素是否相同。使用equals。都一样时就会存入失败。

哈希:取出元素的方法就一个:迭代。

Iterator it = hs.iterator();//这个是接口对象,接受一个子类对象。但是这个被封装起来了。

while(it.hasNext()){

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

}

<按照名字和年龄一致才删除>使用hash写出来,对hash的了解就很好。

Set例题

需求:

往TreeSet集合中存储自定义对象学生。

想按照学生的年龄进行排序。

记住:排序时,当主要条件相同时,一定要判断一下次要条件

【重写的compareTo方法】

public int compareTo(Object obj){

if(!(obj instanceof student))

throw new RuntimeException(“不是学生对象”);

Student s = (Student)obj;

Sop(this.name+”......compareTo.........”+s.name);

if(this.age>s.age)

return 1;

if(this.age==s.ags)

return this.name.compareTo(s.name);///迷人的地方

return -1;

}

泛型<>

 

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

比较记忆模型<泛型的由来>:数组在定义时都明确的存储数据的类型,所以在编译时期就可以发现错 误。但是集合在初始化的时候我们没有明确其类型,所以会发生安全隐患。(编译正常,运行出错)

好处:

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

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

泛型类前期做法:工具类(方法有:设置获取)接收Object类型对象,为了调用者传入的数据都能接收(set    易懂)。然后调用类想取出工具类中的对象就需要强转(也就是调用者类型)。这时没有泛型。

泛型类出现后:改变了格局,是程序员方便了很多。工具类前期指定类型,调用时就避免了强转。

<>: 什么时候用?

当操作的引用数据类型不确定的时候:早期使用Object完成扩展,现在使用泛型类<>来完成。

将要操作的引用数据类型传入即可。(基本数据类型不可以)。

----------------------------------------------------------------------------------

 

例子:

Class Demo<T>{       //泛型类

Public void show(T t){

Sop(“show:”+t);

}

Public void print(Tt){

SOP(“print”+t);

}

}

Class GenerricDemo{

Public static void main(String [] args){

Demo<Integer> d=newDemo<Integer>();

D.show(new Integer(4));

D.print(9);          //有个自动装箱

}

}        //缺点:就是类确定了类型,那么它的方法就确定了。若想操作String,那么就需要           在此创建Demo对象,为String类型。

为了让不同方法可以操作不同类型,而且类型还不确定。那么就可以将泛型定义在方法上。

---------------------------------------------------------------------------------------------------------

Class Demo{

Public <T> void show(T  t){        //泛型方法

SOP(“show:”+t);

}public <T> void prit(T  t){

SOP(“print:”+t);

}        //T是局部变量所以可以一样。

}        //这时在调用的时候就可以传任意类型,泛型的好处显而易见。

----------------------------------------------------------------------------------------------------------

泛型类和泛型方法并用时,方法泛型为主。很牛!

 

注意:      静态方法不可以访问类上定义的泛型,

如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

泛型接口:

把泛型定义在接口上,实现有两个方式:

①:class InterImpl inplements Inter<T>{} --->程序员指定泛型中的类型

②:class InterImpl<T> inplementsInter<T>{}----> 调用者指定泛型中类型

错误提醒:ArrayList<Student> al=newArrayList<Person>();[左右两边不匹配]。

ArrayList al = new ArrayList<Integer>();

 

泛型问题的提升:

解决类型安全问题,------------------出现泛型。

解决指定类型,------------------------出现泛型类。

解决指定的方法类,和静态。------出现了泛型方法。

解决类型不确定,---------------------出现了泛型通配符?

解决类不确定,但是不准出现范围以外的类型,[术语:泛型限定]

-----------出现了泛型通配符继承了指定类型。<? extends Person>

泛型方法:

     其实<>就是一个用于接收具体引用数据类型的参数范围。 

在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型 。

泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除

为什么擦除呢?因为为了兼容运行的类加载器

泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者在强制转换了。

泛型的通配符:? 未知类型。

泛型的限定:

? extends E: 接收E类型或者E的子类型对象。--------[上限](用的多些)

一般存储对象的时候用。-----比如添加元素 addAll.

? super E: 接收E类型或者E的父类型对象。-----------[下限](用的很少)

一般取出对象的时候用。-----比如比较器。【难点】

class WorkerComp implementsComparator<Worker>{

public int compare(Worker s1,Worker s2){

return s1.getName().compareTo(s2.getName());

}

}class StudentComp implementsComparator<Student>{

public int compare(Student s1,Student s2){

return s1.getName().compareTo(s2.getName());

}

}class Comp implementsComparator<Person>{

public int compare(Person p1,Person p2){

returnp1.getName().compareTo(p2.getName());

}        //比较器的泛型,有扩展性;

}        //其中PersonWorkerStudent的父类。

 

||  多态的弊端就是不能预先使用子类的特有方法。

||  泛型的弊端也是,不能使用类型特有的方法,但是tostring可以使用。

 

MAP

 

接口 Map<K,V>Kkey--->键;Vvalue-->值。

Map集合:该集合存储键值对。一对一对的存储。而且要保证键的唯一。

方法解析:[Map<String,String>map = new HashMap<String,String>();]

1,添加。

put(K key , V value)----将指定的值与此映射中的指定键关联(可选操作)。

Map.put(“04”,”null”);----根据返回值是:返回旧值,植入新值。

putAll(Map<? extends K , ? extends V>m)----从指定映射中将所有映射关系复制到此映射中(可选操作)。

2,删除。

clear()----从此映射中移除所有映射关系(可选操作)。

Remove(Object  key)----如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

3,判断。

containsValue(Object  value)----如果此映射将一个或多个键映射到指定值,则返回 true。

containsKey(Objedt  key)----如果此映射包含指定键的映射关系,则返回 true。

map.containsKey(“0222”);

isEmpty()----如果此映射未包含键-值映射关系,则返回 true。

4,获取。

get(Object key)----返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。

Map.get(“04”);//可以通过get方法的返回值来判断一个键是否存在。

size()----返回此映射 中的键-值映射关 系数。

values()----返回此映射中包含的值的 Collection 视图。

---Collection<String>coll=map.values();

[重点]

||--Set<Map.Entry<K,V>>  entrySet()    --返回此映射中包含的映射关系Set视图。

将Map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry

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

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

While(it.hasnext()){

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

String key = me.getKey();

String value = me.getValue();SOP(....);

}

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

Interface Map{

Punlic static interface Entry{//

public abstract Object getKey();

public abstract Object getValue();

}

}class HashMap implements Map{

Class Hash Implements Map.Entry{

Public Object getKey(){}

Public Object getValue(){}

}

}---内部规则的原因是:类名使用、、、没有Map就没有映射关系所以它定义在Map          部。内部类,内部接口。

 

||--Set<K>  keySet               --返回此映射中包含的键的Set 视图。

将map中所有的键存入到Set集合,因为set具备迭代器。所有可以迭代方式取出所有的键,      再根据get方法,获取每一个键对应的值。[所有键获取值]                 

Set<String> keySet = map.keySet();//先获取map集合的所有键的Set集合,keySet();

Iterator<String> it =keySet.iterator();//有了Set集合,就可以获取其迭代器。

while(it.hasNext()){

String key = it.next();

String value = map.get(key);//有了键可以通过map集合的get方法获取其对应的                                                  值。

System.out.println(“key:”+key+”,value:”+value);

}

Map集合的取出原理:将map集合转成set集合。再通过迭代器取出。

--------------------------------------------------------------------------------------------------

例题:

每一个学生都有对应的归属地。学生student,地址String。

学生归属:姓名,年龄。

注意:姓名和年龄相同视为同一个学生。

保证学生的唯一。

--->代码体现:1,描述学生;

2,定义map容器,将学生作为键,地址作为值。存入。

3,获取map集合中的所有元素。

---->升级:对学生对象的年龄进行升序排序。考虑使用TreeMap。

--->”sdfgzxcvasddfgcvdf”获取该字符串中的字母出现的次数。:a(1)b(2)..

思路:       1,将字符串转换成字符数组,以为要对每一个字母进行操作。

2,定义一个map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。

3,遍历字符数组。

将每一个字母作为键去查map集合。

如果返回null,将该字母和1存入到map集合中

如果返回不是null,说明该字母在map集合已经存在并有对应次数。

那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中。覆盖掉原来键所对应的值。

4,将map集合中的数据变成指定的字符窜形式返回。

-----------------------------------------------------------------------------------------------------

import java.util.*;

class Student implementsComparable<Student> {

         /*同时可以创建多个对象需要被用的时候,一定要做实现,覆盖两个方法。【习惯】 */

         privateString name;

         privateint age;

         Student(Stringname ,int age){

                  this.name=name;

                  this.age=age;

         }publicint compareTo(Student s){

                  int num = newInteger(this.age).compareTo(new Integer(s.age));

                  if(num==0)

                           returnthis.name.compareTo(s.name);

                           returnnum;

         }publicint hashCode(){

                  return name.hashCode()+age*34;

         }//hashcode方法。public boolean equals(Objectobj){

                  if(!(obj instanceof Student))

                           thrownew ClassCastException("类型不匹配");

                  Student s = (Student)obj;

                  return this.name.equals(s.name)&&this.age==s.age;

         }//②想到哈希表或者是哈希Code,就需要复写这两个方法:hashcode equals方法。

         publicString getName(){

                  return name;

         }publicint getAge(){

                  return age;

         }publicString toString(){

                  return "姓名:"+name+"年龄:"+age;

         }}

class MapTest{

         publicstatic void main(String[] args){

                  HashMap<Student,String> hm = newHashMap<Student,String>();

                  hm.put(newStudent("lisi1",20),"beijing");

                  hm.put(newStudent("lisi2",23),"shnaghai");

                  hm.put(newStudent("lisi2",23),"shnagai");

                  hm.put(newStudent("lisi3",25),"nanjing");

                  hm.put(newStudent("lisi4",70),"beiing");

                  //第一种取出方式 keySet

                  Set<Student> keySet =hm.keySet();

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

                  while(it.hasNext()){

                           Studentstu = it.next();

                           Stringaddr = hm.get(stu);

                           System.out.println(stu+"...."+addr);

                  }

                  //第二种取出方式 entrySet

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

                  Iterator<Map.Entry<Student,String>>iter = entrySet.iterator();

                  while(iter.hasNext()){

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

                           Studentstu = me.getKey();

                           Stringaddr = me.getValue();

                           System.out.println(stu+"......."+addr);

                  }

         }

}

-------------------------------------------------------------------------------------------------------

注意:

当发现有映射关系时,可以选择map集合。因为map集合中存放就是映射关系。

为什么使用map集合呢?

当数据之间存在着映射关系时,就要先想map集合。

Map集合中存储的都是键值对,打印事就是打印:

Map          :

|---Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步[1.0,低效]

|

|---HashMap:底层是哈希表数据结构,允许使用null键和null值,该集合是不同步的。[1.2,高效]

|

|---TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

 和set很像,其实Set底层就是使用了Map集合。

 

 

Map扩展知识。

Map集合被使用是因为具备映射关系。(循环嵌套)两个while。

 

Collections:集合框架的工具类

 

是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,于Java的Collection框架。

public static <T extendsComparable<?Super T>> void sort(List<T> list)

Public static <T> voidsort(List<T> list){ }//T具有比较性

可以根据元素的自然顺序对指定列表进行排序。

 

方法:Collections,max()

public static <T extendsComparable<?Super T> & Object> void max(Collection<? extends T> coll)

binarySearch(List<?Extends Comparable<? Super T>> list,T key)--需要有序

Fill()----replaceAll(list,”aaa”,”pp”)----reverse(list)反转

reverseOrder()返回的是比较器,反转。

Collections.reverseOrder(newString StrLenComparator())

集合中那么多的对象,特点就是线程不安全,需要被多线程操作时:需要枷锁(枷锁)。

把不安全的集合给它,返回的就是安全的。

staticCollection<T> synchronizedCollection(Collection<T>c)

staticList<T> synchronizedList(List<T> list)返回指定列表支持的同步(线程安全)列表

staticMap<T> synchronizedMap(Map<K,V> map)返回由指定映射支持的同步(线程安全)列表

底层如何实现的:<源码>

SynchronizedList(List<E>list){

Super(list);

This.list =list

}SynchronizedList(List<E>list,Object mutex){

Super(list,mutex);

This.list =list

}//覆盖了equals,hashcode方法。

Public voidadd(int index , E element){

Synchronized(mutex){returnlist.set(index,element);}

}//封装是你传递的list,mutex是同步代码块,使用的是同一个锁。

swap(list,1,2)表示的是把list集合中的角标1的元素和角标2的元素换位置。

shuffle(list)表示随机源的将list排序 [类似洗牌]

Arrays用于操作数组的工具类。

里面都是静态方法。

方法有:查找(二分),对象二分(equals);复制(头尾-->新数组);

比较(比较数组是否一样;比较容器元素是否一样;)fill(替换,头尾);hashcode;

Sort(排序,局部排序);toString(返回指定数组内容的字符串表示形式。);

 

asList将数组变成list集合

String[] arr = {“abc”,”cddd”,”cdsa”};

List<String> list = Array.asList(arr);

sop(list);

----->把集合变成list集合有什么好处?--可以使用集合的思想和方法来操作数组。

注意:将数组变成集合,不可以使用集合的增删方法。因为数组的长度是固定。否则就会  产生UnsupportedOperationException不支持此操作的异常。

---->注意如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。

如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

int[] nums = {1,43,3};                            Integer[] num = {1,3,46};

List lin = Array.asList(nums);                 Integer<Integer> li =Array.asList(nums);      

集合变数组:(toArray

方法:toArray(T[]  a)返回包含此Collection中所有元素的数组;返回数组的运行时类型与指定数组的                                      运行时的类型相同。

①:指定类型的数组到底要定义多长呢?

当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。         当指定类型的数组长度大于了集合的size,就不会新创建数组了,而是使用传递进来的数组。

所以创建一个刚刚好的数组最优。

String[] arr = al.toArray(new String[al.size()]);

②:为什么要将集合变成数组呢?

为了限定对元素的操作,不需要进行增删了。

迭代器升级(高级for循环):

格式:

for(数据类型 变量名 : 被遍历的集合(Collection)或者数组){}

代码:for(String s : al){sop(s);}  遍历al集合,并打印出来。底层原理还是迭代器,优化了书写。

局限:就是只能对集合中的元素进行取出,不能做修改删除等动作。

迭代器:除了遍历,还可以进行remove集合中的元素的动作。

如果使用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

传统for和高级for有什么区别?

高级for有一个局限性:必须有一个被遍历的目标。

建议,在遍历数组的时候,还是使用传统的for。因为传统for可以定义角标。

HashMap集合的元素取出来,使用高级for(键和值都想取出来)

凡是支持迭代器的集合都可以使用高级for,Map不支持迭代,所以转换成Set。

HashMap<Integer,String>hm = new HashMap<Integer,String>();

hm.put(“1”,”a”);hm.put(“2”,”b”);hm.put(“3”,”c”);

Set<Integer>keySet = hm.keySet();

For(Integer i :keySet){

System.out.println(i+”.......”+hm.get(i));

}Set<Map.Entry<Integer,String>>entrySet = hm.entrySet();

For(Map.Entry<Integer,String>me : entrySet)

For(Map.Entry<Integer,String>me : hm.entrySet()){

System.out.println(me.getKey()+”------------”+me.getValue());

}

JDK1.5版本出现的新特性

-----》加法的重载,可以使用传递数组就可以,但是每次都得新建一个数组。一方法=多方法。

------》不传递数组了,直接传递数据。可变参数。其实就是上一种数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。

show(2,3,4,5,6,5);

public static voidshow(int...arr){sop(arr.length);}

①方法的可变参数

注意:在使用是,可变参数一定要定义在参数列表最后面。

public static voidshow(String str,int...arr){sop(arr.length);}//int为类型均可。

②静态导入:StaticImport

import static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

当导包之后,    当类名重名时,需要指定具体的包名。

当方法重名时,指定具备所属的对象或者类。(不可以出现可混淆的可能)

很好的例子:

import static java.lang.System.*;//导入的是System这个类中的所有静态成员

然后就可以是:System.out.println();--->out.println();

 

几个重要的对象

System不可以被实例化。其中的方法和属性都是静态的。

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

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

方法:Properties getProperties() 获取系统属性信息。

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

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

properties ni =System.getProperties();

//获取所有属性信息:

for(Object obj =ni.keySet()){String value

=(String)ni.get(obj); sop();}

强转了类型---Object->String。

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

System.setProperty(“makey”,”mayvalue”);

//获取指定属性的信息

String value =System.getProperty(“os.name”);sop();当不存在时则为null

//可不可以在java虚拟机启动时,动态的加载一些信息呢?

cmd中:java-Dhaha=qqqq SystemDemo//java文件,前面为动态的加载然后就可以使用了。

V=qqqq

Runtime

[类,没有构造函数时,那么就是不能创建对象。然后有方法时就是静态的,然而不是静态时,那么       该类就应该给我提供一个可以使用的对象:获取该对象的方法必须是静态的而且返回值类型是该类类 ]

方式为:static Runtime getRuntime();

每一个java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连。可以通过          getRuntime方法获取对当前运行时 。应用程序不可以创建自己的Runtime类实例。[单例设计模式]

要讲的方法:

//在单独的进程中执行指定命令和变量。

Process  exec(String command)

--->可以打开任意的win下的.exe文件:Runtime.getRuntime().exec(“winmine.exe”);//需要抛出异常。\>\\

Process:

ProcessBuilder.start()和Runtime方法创建一个本机进程,并返回Process子类的一个实例,该实例可用来控制进程并获得相关信息。Process类提供了执行从进程输入、执行输出到进程、等待进城完成、检查进城推出状态以及销毁进程的方法

方法:

【Process destroy();杀掉子进程、很牛的一个。速度很快、由于速度快所以可以:Thread.sleep(4000);等待四秒。】

-----------只能删能获取进程对象的线程。拿不到对象就杀不了。-----------

 

很牛---:Process p = Runtime.getRuntime().exec(“notepad.exe  SystemDemo.java”);//选择性打开文件

Date

构造方法 Date() 分配Date对象并初始化此对象,以表示分配给他的时间。

Date(longdate)表示自从标准基准时间以来的指定毫秒数。

Date d = new Date();

System.out.println(d);//打印时间看不懂,需要改善。

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

SimpleDateFormat sdf = newSimpleDateFormat(“yyyyMMddE hh:mm:ss”);//E本地化

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

String time = sdf.format(d);

System.out.println(“time=”+time);

单独获取年月日等信息。

Date d = new Date();

SimpleDateFormat sdf = new SimpleDateFormat(“yyyy”);

System..out.println(sdf.format(d));//由于打印的是字符串,所以需要转成数。[老方法]

 

class CalendarDemo{

Public static void main(String[] args){

Calender c = Calendar.getInstance();

Sop(“星期”+c.get(Calendar.DAY_OF_WEEK));

}

}

查表法:

String[] mons = {“一月”,”二月”,”三月”,”四月”,”五月”,”六月”,”七月”,”八月”,”九月”};

Int index =c.get(Calendar.YEAR)+”年”);sop(mons[index]); 

 

对实例的时间获取,除了get还有set()设置时间。

如:c.set(2012,2,23);

c.add(Calendar.MONTH,-1); 往前推一个月。

C.add(Calendar.DAY_OF_MONTH,18);18天的日期。

 

Math

包含用于执行基本数学运算的方法。

abs()///返回绝对值

double d = Math.ceil(12.34);///特点ceil 返回大于指定数据的最小整数;

double d1 = Math.floor(12.34);//特点ceil 返回小于指定数据的最小整数;

Long l = Math.round(12.34);//四舍五入

Double d2 = Math.pow(2,3);//次幂运算

Public static double random() 返回代正号的double值,[该值>=0&<1]伪随机数,借助了随机数生成器。

double d = Math.random();数字之间转换,(int)。

Random r = new Random(); int d =r.nextInt(10)+1;Random类的使用。

------- android培训java培训、期待与您交流! ---------- 

0 0
原创粉丝点击