Java语言基础-常用对象API(二)泛型、Map集合

泛型

是JDK1.5出现的安全机制。

好处:
1.将运行时期的问题ClassCastException转到了编译时期;
2.避免了强制转换的麻烦;

<> 什么时候用?        当操作的引用数据类型不确定的时候,就使用<>,将要操作的引用数据类型传入即可。
<>就是一个用于接收具体引用数据类型的参数范围。

在程序中,只要用到了带有<>的类或者借口,就要明确传入的具体引用数据类型;
泛型技术是给编译器使用的技术,用于在编译时期确保类型的安全;
运行时,会将泛型去掉,生成的class文件中不带有泛型。这个称为泛型的擦除。
为什么擦除?    因为为了兼容运行时的类加载器。

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

当方法静态时,不能访问类上定义的泛型,如果静态方法使用方法, 只能将泛型定义在方法上。
当定义了泛型时,不能使用具体的方法。

泛型使用示例:

package cn.ticast.p4.generic.define.demo;



public class GenericDemo4 {

    public static void main(String[] args){

        Tool<String> tool=new Tool<String>();

        

        tool.show(new Integer(4));

        tool.show("abc");

        tool.print("hahah");

        Tool.method("haha");

    }

}



package cn.ticast.p4.generic.define.demo;



//jdk1.5以后,使用泛型来接收类中要操作的引用数据类型

//泛型类:当类中操作的引用数据类型不确定时,使用泛型来表示

public class Tool<QQ>{

    private QQ q;



    public QQ getObject() {

        return q;

    }



    public void setObject(QQ object) {

        this.q = object;

    }

    

    /**

     * 将泛型定义在方法上

     * @param str

     */

    public <w> void show(w str){

        System.out.println("show:"+str);

    }

    public void print(QQ str){

        //System.out.println("print:"+str.length());//错误,当定义了泛型时,不能使用具体的方法。

        System.out.println("print:"+str);

    }

    

    /**

     * 当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,

     * 只能将泛型定义在方法上

     */

    public static <Y> void method(Y obj){//静态方法不需要对象

        System.out.println("method:"+obj);

    }    

}





泛型接口示例:

package cn.ticast.p4.generic.define.demo;



public class GenericDefineDemo5 {

    public static void main(String[] args) {

        InterImpl1 in=new InterImpl1();

        in.show("abc");

        

        InterImpl2<Integer> in2=new InterImpl2<Integer>();

        in2.show(5);

    }



}



//泛型接口,将泛型定义在接口上

interface Inter<T>{

    public void show(T t);

}

 

class InterImpl1 implements Inter<String>{

    public void show(String str){

        System.out.println("show:"+str);

    }

}



class InterImpl2 <Q> implements Inter<Q>{

    public void show(Q q){

        System.out.println("show:"+q);

    }

}




泛型的通配符:? 未知类型
可以对类型进行限定  ? extends E:接收E类型或者子类型对象,上限
                         ?  super E:接收E类型或者E的福类型,下限
一般来说,在存储元素的时候使用上限,因为这样都是按照上限类型来运算的,不会出现类型安全隐患。

class TreeSet<E>
{
     Tree(Comparator<? super E> comp);
}
什么时候使用下限?通常对集合中的元素进行取出操作时,可以使用下限。

上限体现:
 

package cn.ticast.p5.generic.advance.demo;



import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;



import cn.itcast.p2.bean.Person;

import cn.itcast.p2.bean.Student;

import cn.itcast.p2.bean.Worker;



public class GenericAdvanceDemo3 {



    /**

     * @param args

     */

    public static void main(String[] args) {

        ArrayList<Person> al1 = new ArrayList<Person>();



        al1.add(new Person("abc", 30));

        al1.add(new Person("hehe", 34));



        ArrayList<Student> al2 = new ArrayList<Student>();

        al2.add(new Student("stu1", 11));

        al2.add(new Student("stu2", 22));



        ArrayList<Worker> al3 = new ArrayList<Worker>();

        al3.add(new Worker("stu1", 11));

        al3.add(new Worker("stu2", 22));



        ArrayList<String> al4=new ArrayList<String>();



        al4.add("abcdefg");

//        al1.addAll(al4);//有泛型限定之后,al4不能添加到al1(类型不匹配,此处只能是Person及其子类);如果没有泛型限定,能够传入,但是有安全隐患,取出时会出错

        al1.addAll(al2);//有泛型限定之后,能够添加。Student是Person的子类

        al1.addAll(al3);

        

//        printCollection(al);

//        printCollection(al2);



    }

    

/*

 * 一般在存储元素的时候使用上限,以为这样都是按照上限类型来运算的,不会出现类型安全隐患

 */

class MyCollection<E>{

    public void add(E e){

        

    }

    public void addAll(MyCollection<? extends E> al){

        

    }

}    

}



下限体现:

package cn.ticast.p5.generic.advance.demo;



import java.util.Comparator;

import java.util.Iterator;

import java.util.TreeSet;



import cn.itcast.p2.bean.Person;

import cn.itcast.p2.bean.Student;

import cn.itcast.p2.bean.Worker;



public class GenericAdvanceDemo4 {



    /**

     * @param args

     */

    public static void main(String[] args) {

        TreeSet<Person> al1 = new TreeSet<Person>(new CompByName());



        al1.add(new Person("abc4", 30));

        al1.add(new Person("abc1", 34));

        al1.add(new Person("abc2", 38));



        TreeSet<Student> al2 = new TreeSet<Student>(new CompByStName());

        al2.add(new Student("stu1", 11));

        al2.add(new Student("stu7", 20));

        al2.add(new Student("stu2", 22));



        TreeSet<Worker> al3 = new TreeSet<Worker>();

        al3.add(new Worker("stu1", 11));

        al3.add(new Worker("stu2", 22));



        TreeSet<String> al4=new TreeSet<String>();



        al4.add("abcdefg");

//        al1.addAll(al4);

        

//        al1.addAll(al2);

//        al1.addAll(al3);



//        System.out.println(al1.size());

        

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

        while(it.hasNext()){

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

        }

    }

    

    

}



/*

 * class TreeSet<E>

 * {Tree(Comparator<? super E> comp);}

 * 

 * 什么时候使用下限?通常对集合中的元素进行取出操作时,可以使用下限。

 */

class CompByName implements Comparator<Person>{



    @Override

    public int compare(Person o1, Person o2) {

        int temp=o1.getName().compareTo(o2.getName());

        return temp==0?o1.getAge()-o2.getAge():temp;

    }

    

}



class CompByStName implements Comparator<Student>{



    @Override

    public int compare(Student o1, Student o2) {

        int temp=o1.getName().compareTo(o2.getName());

        return temp==0?o1.getAge()-o2.getAge():temp;

    }

    

}



通配符应用:

package cn.ticast.p5.generic.advance.demo;



import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;



import cn.itcast.p2.bean.Person;



public class GenericAdvanceDemo5 {



    /**

     * @param args

     */

    public static void main(String[] args) {

        ArrayList<Person> al1 = new ArrayList<Person>();

        al1.add(new Person("abc", 30));

        al1.add(new Person("abc4", 34));

        

        ArrayList<Person> al2 = new ArrayList<Person>();

        al2.add(new Person("abc22222", 30));

        al2.add(new Person("abc422222", 34));

        

        al1.containsAll(al2);



        ArrayList<String> al4 = new ArrayList<String>();

        al4.add("abcdefg");

        al4.add("abc");

        al1.containsAll(al4);



        Iterator<Person> it = al1.iterator();

        while (it.hasNext()) {

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

        }

    }



    public static void printCollection(Collection<?> al) {

        Iterator<?> it = al.iterator();// Collection<? extends

        while (it.hasNext()) {

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

        }

    }

}



class MyCollection2<E>{

    public boolean containsAll(Collection<?> coll){

        

        return true;

    }

}



集合查阅技巧:
是否需要唯一?
需要:Set
    是否需要指定顺序?
        需要:TreeSet
        不需要:HashSet
        想要一个和存储一致的顺序(有序):LinkedHashSet
不需要:List
    是否需要频繁增删?
        需要:LinkedList
        不需要:ArrayList

如何记住每个容器的结构和所属体系?
看名字:
List
    |--ArrayList
    |--LinkedList

Set
    |--HashSet
    |--TreeSet

后缀名就是该集合所属的体系。

前缀名就是该集合的数据结构。
array,数组,查询速度快,有脚标;
link,链表,增删速度快,add、get、remove、first last方法;
hash,哈希表,唯一性,元素需要覆盖hashCode方法和equals方法;
tree,二叉树,排序,两个接口Comparable、Comparator;

而且通常这些常用的结合容器都是不同步的。


Map:一次添加一对元素,Collection一次添加一个元素。
Map也称为双列集合,Collection称为单列集合。
特点:
-Map集合中存储的是键值对。
-Map集合中必须保证键的唯一性。

常用方法:
1.添加
value put(K key, V value); //返回上一个与key关联的值,如果没有则返回null。
2.删除
void clear();//清空map集合
value remove(Object key); //根据指定的key,删除这个键值对
3.判断
boolean containsKey(key);//如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(key);//如果此映射将一个或多个键映射到指定值,则返回 true。
boolean isEmpty();//如果此映射未包含键-值映射关系,则返回 true。
4.获取
value get(Object key); //通过键获取值,如果没有该键则返回null;可以通过返回null,来判断是否包含指定键。
int size();//获取键值对的个数。
Set<K> keySet();// 返回此映射中包含的键的 Set 视图。

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

public static interface Map.Entry<K,V>映射项(键-值对)。
Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。

Collection<V> values();//返回此映射中包含的值的 Collection 视图。

Map常见方法示例:

package cn.ticast.p6.map.demo;



import java.util.Collection;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;



public class MapDemo {

    public static void main(String[] args) {

        Map<Integer, String> map = new HashMap<Integer, String>();

        // method(map);

        method_2(map);



    }



    public static void method_2(Map<Integer, String> map) {

        map.put(8, "wangwu");

        map.put(2, "zhaoliu");

        map.put(7, "xiaoqiang");

        map.put(6, "wangcai");



        //只要姓名,不要键

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

        Iterator<String> it3 = values.iterator();

        while (it3.hasNext()) {

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

        }



        /*

         * 第二种 通过Map转成Set就可以迭代 找到了另一个方法:entrySet

         * 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型

         */

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

        Iterator<Map.Entry<Integer, String>> it2 = entrySet.iterator();

        while (it2.hasNext()) {

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

            Integer key = me.getKey();

            String value = me.getValue();

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

        }



        /*

         * 第一种 取出map中的所有元素 原理:先通过keySet方法,获取map中所有的键所在的Set集合,再通过Set的迭代器,

         * 获取到每一个键,从而用map的get方法获取每个键对应的值

         */



        // Set<Integer> keySet = map.keySet();

        // Iterator<Integer> it1 = keySet.iterator();

        // while (it1.hasNext()) {

        // Integer key = it1.next();// 通过迭代器获取每个键

        // String value = map.get(key);// 使用get方法,通过每个键获取对应的值

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

        // }



    }



    public static void method(Map<Integer, String> map) {// 序号和姓名

        // 添加元素

        System.out.println(map.put(8, "wangcai"));// null

        System.out.println(map.put(8, "xiaoqiang"));// wangcai,存相同键,值会覆盖

        map.put(2, "zhangsan");

        map.put(7, "zhaoliu");



        // 删除

        // System.out.println("remove:"+map.remove(2));



        // 判断

        System.out.println("contains key:" + map.containsKey(7));



        // 获取

        System.out.println("get:" + map.get(8));

        System.out.println(map);

    }

}



Map常用的子类对象:
    |--HashTable    :内部结构是哈希表,是同步的。不允许null作为键和值※
        |--Properties:用来存储简直对型的配置文件的信息。可以和IO技术相结合、
    |--HashMap    :内部结构是哈希表,不是同步的。允许null作为键和值※
    |--TreeMap    :内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。

HashMap应用示例:

package cn.ticast.p6.hashmap.demo;



import java.util.HashMap;

import java.util.Iterator;



import cn.itcast.p2.bean.Student;



public class HashMapDemo {



    public static void main(String[] args) {

        /*

         * 将学生对象和学生的归属地,通过键与值存储到map集合中

         */



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

        hm.put(new Student("lisi", 38), "北京");

        hm.put(new Student("zhaoliu", 24), "上海");

        hm.put(new Student("xiaoqiang",31), "沈阳");

        hm.put(new Student("wangcai", 28), "大连");

        hm.put(new Student("zhaoliu", 24), "铁岭");



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



        while (it.hasNext()) {

            Student key = it.next();

            String value = hm.get(key);

            System.out.println(key.getName() + ":" + key.getAge() + "----"

                    + value);

        }

    }

}



TreeMap应用示例:

package cn.ticast.p8.treemap.demo;



import java.util.Iterator;

import java.util.Map;

import java.util.TreeMap;



import cn.itcast.p2.bean.Student;

import cn.ticast.p3.comparator.ComparatorByName;



public class TreeMapDemo {



    public static void main(String[] args) {

        /*

         * 将学生对象和学生的归属地,通过键与值存储到map集合中

         * 使用比较器Comparator,按姓名排序

         */



        TreeMap<Student, String> tm = new TreeMap<Student, String>(new ComparatorByName());

        tm.put(new Student("lisi", 38), "北京");

        tm.put(new Student("zhaoliu", 24), "上海");

        tm.put(new Student("xiaoqiang", 31), "沈阳");

        tm.put(new Student("wangcai", 28), "大连");

        tm.put(new Student("zhaoliu", 24), "铁岭");



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



        while (it.hasNext()) {

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

            Student key = me.getKey();

            String value = me.getValue();

            System.out.println(key.getName() + ":" + key.getAge() + "----"

                    + value);

        }

    }

}

package cn.ticast.p3.comparator;



import java.util.Comparator;



import cn.itcast.p2.bean.Person;



public class ComparatorByName/*extends Object*/ implements Comparator<Person> {



    @Override

    public int compare(Person o1, Person o2) {

        int temp=o1.getName().compareTo(o2.getName());

        return temp==0?o1.getAge()-o2.getAge():temp;

    }

}



LinkedHashMap:使用LinkedHashMap,则有序(存取顺序相同)
LinkedHashMap应用示例:

package cn.itcast.p1.map.demo;



import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Map;



public class LinkedHashmapDemo {

    public static void main(String[] args) {

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



        hm.put(7, "zhouqi");

        hm.put(3, "zhangsan");

        hm.put(1, "qianyi");

        hm.put(5, "wangwu");



        Iterator<Map.Entry<Integer, String>> it = hm.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);

        }

    }

}



Map集合练习:

package cn.itcast.p1.map.test;



import java.util.Iterator;

import java.util.Map;

import java.util.TreeMap;



/*

 * 练习:

 * "fdqavchsacdfs"获取该字符串中,每一个字母出现的次数。

 * 要求打印的结果是a{2}b{1}...;

 * 思路:

 * 对于结果的分析发现,字母和次数之间存在着映射的关系,而且这种关系很多

 * 所以需要存储,能存储映射关系的容器有数组和Map结合

 * 关系一方是否是有序编号?否

 * 那就使用Map集合。又发现可以保证唯一性的一方具备着顺序,如a、b、c……

 * 所以可以使用TreeMap集合。

 * 

 * 这个集合中,最终应该存储的是字母和次数的对应关系

 * 1.因为操作的是字符串中的字母,所以先将字符串变为字符数组;

 * 2.遍历字符数组,用每一个字母作为键去查Map集合这个表;

 *      如果该字母键不存在,则将该字母作为键,1作为值存储到Map集合中;

 *      如果该字母键存在,则将该字母对应的值取出,并自增,再将该字母和+1后的值存储到Map集合中;

 *      键相同,值会覆盖。这样,就记录住了该字母的次数;

 * 3.遍历结束,Map集合中就记录了所有字母出现的次数。

 */

public class MapTest {

    public static void main(String[] args) {

        String str = "fd++qa--vc   hsacdfs";



        String s = getCahrCount(str);



        System.out.println(s);

    }



    public static String getCahrCount(String str) {

        // 将字符串变成字符数组

        char[] chs = str.toCharArray();



        // 定义Map集合表

        Map<Character, Integer> map = new TreeMap<Character, Integer>();



        // 遍历

        for (int i = 0; i < chs.length; i++) {

            if(!(chs[i]>='a'&&chs[i]<='z'||chs[i]>='A'&&chs[i]<='Z'))

                continue;

            // 将数组中的数组作为键去查Map表

            Integer value = map.get(chs[i]);

            // 判断值是否为null

            int count = 1;

            if (value != null) {

                count = value + 1;

            }

            map.put(chs[i], count);



            /*

             * if(value==null){ map.put(chs[i], 1); }else{ map.put(chs[i],

             * value+1); }

             */

        }

        return mapToString(map);

    }



    private static String mapToString(Map<Character, Integer> map) {

        StringBuilder sb=new StringBuilder();

    

        Iterator<Character> it=map.keySet().iterator();

        while(it.hasNext()){

            Character key=it.next();

            Integer value=map.get(key);

            

            sb.append(key+"{"+value+"}");

        }

        return sb.toString();

    }

}





package cn.itcast.p1.map.test;



import java.util.HashMap;

import java.util.Map;



public class MapTest2 {

    public static void main(String[] args) {

        /*

         * Map在有映射关系时,可以优先考虑

         * 

         * 在查表法中的应用较为多见

         */



        String week = getWeek(1);

        System.out.println(week);

        

        System.out.println(getWeekByMap(week));

    }



    public static String getWeekByMap(String week) {

        Map<String, String> map = new HashMap<String, String>();

        map.put("星期一","Mon");

        map.put("星期二","Tus");

        map.put("星期三","Wes");

        map.put("星期日","Sun");

        map.put("星期天","Sun");

        return map.get(week);

    }



    public static String getWeek(int week) {

        if (week < 1 || week > 7)

            throw new RuntimeException("没有对应的星期,请重新输入");

        String[] weeks = { "", "星期一", "星期二" };



        return weeks[week];

    }

}




Collections工具类
Collections是集合框架的工具类,里边的方法都是静态的。

static <T extends Comparable<? super T>> void  sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。

static <T> int  binarySearch(List<? extends Comparable<? super T>> list, T key)
使用二分搜索法搜索指定列表,以获得指定对象。
使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过 sort(List) 方法)。如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。
如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。

static <T extends Object & Comparable<? super T>> T  max(Collection<? extends T> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。

static <T> Comparator<T>  reverseOrder()          
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。

static void reverse(List<?> list)
反转指定列表中元素的顺序。

static <T> boolean  replaceAll(List<T> list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。

static <T> void  fill(List<? super T> list, T obj)
使用指定元素替换指定列表中的所有元素。

static void shuffle(List<?> list)
使用默认随机源对指定列表进行置换。

static <T> Enumeration<T>  enumeration(Collection<T> c)
返回一个指定 collection 上的枚举。


给非同步的集合加锁
List list=new ArrayList();//非同步的
list=MyCollections.Synchronized(list);//返回一个同步的list

class MyCollections{



    public static List synchronized(List list){

        return new MyList(list);

    }



}

private class MyList implements List{

    private List list;

    pirvate static final Object lock=new Object();

    MyList(List list){

        this.list=list;

    }



    public boolean add(Object obj){

        synchronized(lock)

            {

                return list.add(obj);

            }

    }



public boolean remove(Object obj){

        synchronized(lock)

            {

            return list.remove(obj);

            }

    }

}



static <T> Collection<T>  synchronizedCollection(Collection<T> c)
返回指定 collection 支持的同步(线程安全的)collection。
static <T> List<T>  synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。
static <K,V> Map<K,V>  synchronizedMap(Map<K,V> m)
返回由指定映射支持的同步(线程安全的)映射。
static <T> Set<T>  synchronizedSet(Set<T> s)
返回指定 set 支持的同步(线程安全的)set。
static <K,V> SortedMap<K,V>  synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序映射支持的同步(线程安全的)有序映射。
static <T> SortedSet<T>  synchronizedSortedSet(SortedSet<T> s)
返回指定有序 set 支持的同步(线程安全的)有序 set。


Arrays工具类
Arrays集合框架的工具类,里面的方法都是静态的。

重点: List asList(数组) 将数组转成集合
好处:可以使用结合的方法操作数组中的元素
注意:数组的长度是固定的,所以对于集合的增删方法是不可以使用的,
否则会发生UnsupportedOperationException。

如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
如果数组中的元素是基本类型数值,那么会将数组作为集合中的元素进行存储。

package cn.itcast.p3.toolclass.arrays.demo;



import java.util.Arrays;

import java.util.List;



//数组转成集合

public class ArraysDemo {



    /**

     * @param args

     */

    public static void main(String[] args) {



        // int[] arr={3,1,5,6,3,6};

        // System.out.println(Arrays.toString(arr));



        System.out.println("demo_1");

        demo_1();

        System.out.println("demo_2");

        demo_2();

    }



    public static void demo_2() {

        /*

         * 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。

         * 如果数组中的元素是基本类型数值,那么会将数组作为集合中的元素进行存储。

         */

        int[] arr = { 31, 11, 51, 61 };



        List<int[]> list = Arrays.asList(arr);



        System.out.println(list);

    }



    /**

     * 

     */

    private static void demo_1() {

        String[] arr = { "abc", "haha", "xixi" };

        boolean b = myContains(arr, "xixi");

        System.out.println("contains:" + b);



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

        // list.add("hehe");//数组的长度是固定的,所以对于集合的增删方法是不可以使用的,

        // 否则会发生UnsupportedOperationException。

        boolean b1 = myContains(arr, "xixi");

        System.out.println("list contains:" + b1);

        System.out.println(list);

    }



    public static boolean myContains(String[] arr, String key) {

        for (int i = 0; i < arr.length; i++) {

            if (arr[i].equals(key))

                return true;

        }

        return false;

    }



    // toString的经典实现

    public static String myToString(int[] a) {

        int iMax = a.length - 1;

        if (iMax == -1)

            return "[]";



        StringBuilder b = new StringBuilder();

        b.append('[');

        for (int i = 0;; i++) {// 中间省略条件判断,提高效率

            b.append(a[i]);

            if (i == iMax)

                return b.append(']').toString();

            b.append(", ");

        }

    }

}




集合转成数组
使用的是Collection接口中的toArray方法。
集合转成数组,可以对集合中的元素操作的方法进行限定,不允许对其进行增删。

toArray方法需要传入一个指定类型的数组
长度的定义方法:
如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组;
如果长度大于集合的size,该方法就会使用指定的数组村粗集合中的元素,其他位置默
为null;
建议数组长度是指定的结合的size

package cn.itcast.p3.toolclass.arrays.demo;



import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;



public class ToArray {



    /**

     * @param args

     */

    public static void main(String[] args) {

        /*

         * 集合转成数组

         */

        List<String> list=new ArrayList<String>();

        list.add("abc1");

        list.add("abc2");

        list.add("abc3");

        

        /*

         * toArray方法需要传入一个指定类型的数组

         * 长度的定义方法:

         * 如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组;

         * 如果长度大于集合的size,该方法就会使用指定的数组村粗集合中的元素,其他位置默认为null;

         * 建议数组长度是指定的结合的size

         */

        String[] arr=list.toArray(new String[2]);

        

        System.out.println(Arrays.toString(arr));

    }



}



foreach循环
格式:
for(类型 变量 : Collection集合 | 数组)
{
   
}

传统for循环和高级for的区别:
传统for可以完成对语句执行多次,因为可以定义控制循环的增量和条件;
而高级for是只用简化形式,它必须有被遍历的目标,该目标要么是数组,要么是Collection集合;
对于数组的遍历,如果仅仅是获取数组中的元素,可以使用高级for;如果要对数组的脚标进行操作,建议使用传统for。

package cn.itcast.p4.news.demo;



import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;



public class ForEachDemo {



    /**

     * @param args

     */

    public static void main(String[] args) {



        List<String> list = new ArrayList<String>();



        list.add("abc1");

        list.add("abc2");

        list.add("abc3");



        for (String s : list) {// 简化书写

            System.out.println(s);

        }



        int[] arr = { 3, 1, 5, 6, 7, 2 };

        for (int i : arr) {

            System.out.println(i);

        }



        // 可以使用高级for遍历map集合:不能直接作用,但是可以将map转成单列的set,就可以使用

        Map<Integer,String> map=new HashMap<Integer,String>();

        

        map.put(3, "zhagsan");

        map.put(1, "wangyi");

        map.put(7, "wangwu");

        map.put(4, "zhangsan");

        

        for(Integer key:map.keySet()){

            String value=map.get(key);

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

        }

        for(Map.Entry<Integer, String> me:map.entrySet()){

            Integer key=me.getKey();

            String value=me.getValue();

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

        }

        

        // Iterator<String> it=list.iterator();

        // while(it.hasNext()){

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

        // }

    }

}



函数可变参数
其实就是一个数组,但是接受的是数组中的元素,自动将这些元素封装成数组,简化了调用者的书写。
※注意事项:可变参数类型,必须定义在参数列表的结尾。

package cn.itcast.p4.news.demo;



public class ParamterDemo {

    public static void main(String[] args) {

        int[] arr = { 5, 1, 4, 7, 3 };

        int sum1 = add(arr);

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



        int sum2 = newAdd(5, 1, 4, 7, 3);

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

        int sum3 = newAdd(5, 1, 2, 7, 9, 8, 7, 6);

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

    }



    public static int newAdd(int a,int... arr) {// 可变参数

        int sum = 0;

        for (int i = 0; i < arr.length; i++) {

            sum += arr[i];

        }

        return sum;

    }



    public static int add(int[] arr) {

        int sum = 0;

        for (int i = 0; i < arr.length; i++) {

            sum += arr[i];

        }

        return sum;

    }

}



静态导入

package cn.itcast.p4.news.demo;



//import static java.util.Collections.sort;//其实导入的是类中的静态成员

//import static java.util.Collections.max;

import static java.lang.System.out;

import static java.util.Collections.max;

import static java.util.Collections.sort;



import java.util.ArrayList;

import java.util.List;



public class StaticImportDemo {

    public static void main(String[] args) {

        List<String> list = new ArrayList<String>();



        list.add("abc1");

        list.add("abc2");

        list.add("abc3");



        out.println(list);



        // Collections.sort(list);

        sort(list);



        out.println(list);



        // String max = Collections.max(list);

        String max = max(list);

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

    }



}



其他对象API
System类
public final class Systemextends Object
System 类包含一些有用的类字段和方法。它不能被实例化。
System类中的方法和属性都是静态的。

static long currentTimeMillis(); //返回以毫秒为单位的当前时间。
static String getProperty(String key, String def)
获取用指定键描述的系统属性。
Object setProperty(String key, String value)
调用 Hashtable 的方法 put。

package cn.itcast.p1.otherapi.demo;



import java.util.Properties;

import java.util.Set;



public class SystemDemo {



    private static final String SPACE_SEPARATOR = System

            .getProperty("line.separator");



    /**

     * @param args

     */

    public static void main(String[] args) {



        System.out.println("Hello" + SPACE_SEPARATOR + " World");// 能实现任何系统中的换行

        // demo_0();

        // demo_1();

        

        //给系统设置属性信息,这些信息是全局的,其他程序都可以使用

        System.setProperty("myclasspath", "c:\\myclass");

        

    }



    public static void demo_1() {

        // 获取系统的徐行信息,并存储到了Properties集合中

        /*

         * Properties集合中存储的都是String类型的键和值 最好使用它自己的存储和取出的方法来完成元素的操作

         */

        Properties prop = System.getProperties();



        Set<String> nameSet = prop.stringPropertyNames();



        for (String name : nameSet) {

            String value = prop.getProperty(name);

            System.out.println(name + "::" + value);

        }



    }



    private static void demo_0() {

        long l1 = System.currentTimeMillis();

        System.out.println(l1);

        // System.out.println(l1/1000/60/60/24/365);



        long temp = 1344227567838l;



        long l2 = System.currentTimeMillis();

        System.out.println(l2 - temp);

    }

}



public class Runtimeextends
Object每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。
应用程序不能创建自己的 Runtime 类实例。

Runtime没有构建方法摘要,说明该类不能创建对象。
又发现,Runtime有非静态的方法,说明该类应该提供静态的返回该类对象的方法。
而且只有一个,说明Runtime类使用了单例设计模式完成。※

package cn.itcast.p1.otherapi.demo;



import java.io.IOException;



public class RuntimeDemo {



    /**

     * @param args

     * @throws IOException 

     * @throws InterruptedException 

     */

    public static void main(String[] args) throws IOException, InterruptedException {

        Runtime r=Runtime.getRuntime();

        Process p=r.exec("notepad.exe");

        Thread.sleep(5000);

        p.destroy();

    }

}



Math
public final class Mathextends ObjectMath
类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

常用的方法:
ceil();//返回大于参数的最小整数
floor();//返回小于参数的最大整数
round();//返回四舍五入后的整数
pow(a,b);//返回a的b次方
random();
//返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。

package cn.itcast.p1.otherapi.demo;



import java.util.Random;



public class MathDemo {



    /**

     * @param args

     */

    public static void main(String[] args) {

        // double d1 = Math.ceil(12.56);

        // double d2 = Math.floor(12.56);

        // double d3 = Math.round(12.56);

        //

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

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

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

        //

        // double d = Math.pow(10, 2);

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

        Random r = new Random();

        for (int i = 0; i < 10; i++) {

            // double d = Math.ceil(Math.random()*100);

            

            // double d = (int) (r.nextDouble() * 6 + 1);

            int d = r.nextInt(6) + 1;

            System.out.println(d);

        }

    }

}




Date类
public class Dateextends Objectimplements Serializable, Cloneable, Comparable<Date>

年份 y 由整数 y - 1900 表示。
月份由从 0 至 11 的整数表示;0 是一月、1 是二月等等;因此 11 是十二月。
日期(一月中的某天)按通常方式由整数 1 至 31 表示。
小时由从 0 至 23 的整数表示。因此,从午夜到 1 a.m. 的时间是 0 点,从中午到 1 p.m. 的时间是 12 点。
分钟按通常方式由 0 至 59 的整数表示。
秒由 0 至 61 的整数表示;值 60 和 61 只对闰秒发生,尽管那样,也只用在实际正确跟踪闰秒的 Java 实现中。于按当前引入闰秒的方式,两个闰秒在同一分钟内发生是极不可能的,但此规范遵循 ISO C 的日期和时间约定。

日期对象和毫秒值之间的转换

毫秒值-->日期对象:
1.通过Date对象的构造方法完成 new Date(timeMilis);
2.通过setTime()设置;
目的:可以通过Date对象的方法对该日期中的各个字段(年月日等)进行操作;
日期对象-->毫秒值
getTime();
目的:可以通过具体的数值进行运算;

boolean after(Date when)
测试此日期是否在指定日期之后。

boolean before(Date when)
测试此日期是否在指定日期之前。

boolean equals(Object obj)
比较两个日期的相等性。

int compareTo(Date anotherDate)
比较两个日期的顺序。

String toString()
把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。

对日期对象进行格式化
static DateFormat getDateTimeInstance(int dateStyle, int timeStyle)
获取日期/时间格式器,该格式器具有默认语言环境的给定日期和时间格式化风格。

package cn.itcast.p1.otherapi;



import java.text.DateFormat;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;



public class DateDemo {



    /**

     * @param args

     * @throws ParseException

     */

    public static void main(String[] args) throws ParseException {



        // methodDemo_1();

        // methodDemo_2();

        methodDemo_3();



    }



    /**

     * 日期格式的字符串-->日期对象,使用的是DateFormat类中的parse方法

     * @throws ParseException

     */

    public static void methodDemo_3() throws ParseException {

        String str_date = "2012年4月19日";

        str_date = "2011---8---17";



        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);

        // 只能解析默认风格的日期,如2012-8-17

        // DateFormat dateFormat = DateFormat.getDateInstance();//

        dateFormat = new SimpleDateFormat("yyyy---MM---dd");// 自定义风格



        Date d = dateFormat.parse(str_date);

        System.out.println(d);

    }



    /**

     * 对日期对象进行格式化 日期对象-->日期格式的字符串,使用的是DateFormat类中的format方法

     */

    public static void methodDemo_2() {

        Date date = new Date();



        // 获取日期格式对向,具备着默认风格。FULL、LONG等可以指定风格

        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL);

        dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,

                DateFormat.LONG);



        // 如果风格是自定义的,如何解决

        dateFormat = new SimpleDateFormat("yyyy--MM--dd");



        String str_date = dateFormat.format(date);

        System.out.println(str_date);

    }



    private static void methodDemo_1() {

        long time = System.currentTimeMillis();

        System.out.println(time);// 1344324000837



        Date date = new Date();// 将当前日期和时间封装成对象

        System.out.println(date);// Tue Aug 07 15:17:40 CST 2012



        Date date2 = new Date(1344324000837l);// 将制定毫秒值封装成对象

        System.out.println(date2);

    }

}



Date练习示例:

package cn.itcast.p1.otherapi.test;



import java.text.DateFormat;

import java.text.ParseException;

import java.util.Date;



/*

 * "2012-3-17"到"2012-4-6"

 * 中间有多少天

 * 思路:

 * 两个日期相减。

 * 必须要有两个可以进行减法运算的数。

 * 能相减的可以是毫秒值。使用Date对象获取毫秒值。

 * 从日期格式字符串获取时间。将字符串转成Date对象。

 * 

 * 1.将日期格式的字符串转成对象;

 * 2.将Date对象转成毫秒值;

 * 3.毫秒值相减,然后转换成天数。

 */

public class DateTest {



    /**

     * @param args

     * @throws ParseException

     */

    public static void main(String[] args) throws ParseException {



        String str_date1 = "2012-3-17";

        String str_date2 = "2012-4-6";

        test(str_date1, str_date2);



    }



    public static void test(String str_date1, String str_date2)

            throws ParseException {



        // 1.将日期字符串转成日期对象

        // 定义日期格式对象

        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);

        // dateFormat=new SimpleDateFormat("yyyy-MM-dd");



        //2.将Date对象转换成毫秒值

        Date date1 = dateFormat.parse(str_date1);

        Date date2 = dateFormat.parse(str_date2);

        long time1 = date1.getTime();

        long time2 = date2.getTime();



        //3.毫秒值相减,然后转换成天数

        long time = Math.abs(time1 - time2);

        int day = getDay(time);

        System.out.println(day);



    }



    public static int getDay(long time) {

        return (int) (time / 1000 / 60 / 60 / 24);

    }



}



Calendar类

package cn.itcast.p1.otherapi;



import java.util.Calendar;



public class CalendarDemo {



    /**

     * @param args

     */

    public static void main(String[] args) {



        Calendar c = Calendar.getInstance();



        int year = 2012;

        showDays(year);



    }



    /**

     * @param c

     */

    private static void showDays(int year) {

        Calendar c = Calendar.getInstance();

        c.set(year, 2, 1);

        c.add(Calendar.DAY_OF_MONTH, -1);

        showDate(c);

    }



    /**

     * Calendar c = Calendar.getInstance();

     */

    private static void showDate(Calendar c) {



        int year = c.get(Calendar.YEAR);

        int month = c.get(Calendar.MONTH) + 1;

        int day = c.get(Calendar.DAY_OF_MONTH);

        int week = c.get(Calendar.DAY_OF_WEEK);



        System.out.println(year + "年" + month + "月" + day + "日 "

                + getWeek(week));

    }



    public static String getWeek(int i) {

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



        return weeks[i];

    }



}

你可能感兴趣的:(java语言)