zoukankan      html  css  js  c++  java
  • 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];
        }
    
    }
    
  • 相关阅读:
    第36课 经典问题解析三
    第35课 函数对象分析
    67. Add Binary
    66. Plus One
    58. Length of Last Word
    53. Maximum Subarray
    38. Count and Say
    35. Search Insert Position
    28. Implement strStr()
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/chenchong/p/2627188.html
Copyright © 2011-2022 走看看