java-集合框架

首先我们给一个框架图:(本人认为:集合和映射实际上就是方法的使用,多学习API即可)

框架图

 接着我们一个一个来盘

1.Collection集合:存放的是单一的值
 * 存储不唯一的 无序的对象
 * 特点:
 * 1、可以存放不同类型的数据,而数组只能存放固定类型的数据
 * 2、当使用arraylist子类实现的时候,初始化的长度是10,当长度不够用的时候就会自动扩容
 * 看源码grow();可知会自动>>1位,也就是扩容1.5倍
 * API方法:
 *   增加数据的方法
 *             add:要求必须传入的参数是Object对象,因此当写入基本数据类型的时候,包含了自动拆箱和自动装箱的过程
 *             addAll:添加另一个集合的元素到此集合中
 *
 *             删除数据的方法
 *             clear:只是清空集合中的元素,但是此集合对象并没有被回收
 *             remove:删除指定元素
 *             removeAll:删除集合元素
 *             查询数据的方法
 *             contains:判断集合中是否包含指定的元素值
 *             containsAll:判断此集合中是否包含另一个集合
 *             isEmpty:判断集合是否等于空
 *             retainAll:若集合中拥有另一个集合的所有元素,返回true,否则返回false
 *            size:返回当前集合的大小
 *
 *             //集合转数组的操作
 *            toArray:将集合转换成数组

public class CollectionDemo {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add("abc");
        c.add(123);
        c.add(true);
        c.add(123);
//        c.remove(123);
//        c.clear();
        System.out.println(c.contains(123));
        Collection c1 = new ArrayList();
        c1.add("bcd");
        c1.add("def");
        c1.add(456);
//        System.out.println(c1.addAll(c));
        System.out.println(c1);
        System.out.println(c);
//         c1.removeAll(c1);
//        System.out.println(c1);
        System.out.println(c.isEmpty());
//        System.out.println(c.retainAll(c1));
        System.out.println(c.size());
        Object[] objects = c.toArray();
        for (int i = 0; i <objects.length ; i++) {
            System.out.println(objects[i]);
        }
    }
}

 2.List:存放的是单一的值 存储一组 不唯一 有序的对象

public class ListDemo {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("abc");
        list.add(123);
        list.add(true);
        list.add(123);
        list.add(15.0);
        list.add(1,"OK");
        System.out.println(list);
        System.out.println(list.get(0));
        System.out.println(list.size());
        System.out.println(list.lastIndexOf(123));
        System.out.println(list.indexOf(123));
        System.out.println(list.set(4,"Oyear"));
        System.out.println(list);
        /*跟subString一样都是截取,截头不结尾
        只是subString是截取字符串,subList是截取索引出处的值
         */
        System.out.println(list.subList(0,4));
    }

}

3.

ArrayList
    初始容量是10
底层是由数组实现,但它实现了长度可变的数组(可以进行扩容 一次扩容1.5倍)
优点:遍历元素和随机访问元素的效率比较高
缺点:添加和删除需要移动大量的元素,效率低

     1.ArrayList是非线程安全的,高效率,
2.Vector是线程安全的,低效率
 ArrayList扩容是每次扩容1.5倍,Vector扩容是每次扩容2倍

4.LinkedList实现类
    采用的是链表存储方式
优点:插入删除元素的效率比较高
缺点:遍历和随机访问元素的效率低下

package com.shun.changyong;

import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add("abc");
        linkedList.add(123);
        linkedList.add(true);
        linkedList.add(18.0);
        //在指定位置插入元素
        linkedList.add(0,"Java!");
        LinkedList linkedList1 = new LinkedList();

        //丛指定集合插入第一个元素的索引(如果索引输入为1则会出现数组越界异常)
//        linkedList1.addAll(0,linkedList);
        linkedList1.addAll(linkedList);
        //在列表开头、结尾插入元素
         linkedList.addFirst("加油");
         linkedList.addLast("努力");
//删除集合中所有元素
//         linkedList.clear();
        //判断集合中有没有指定元素 有就true 没有就 false
        System.out.println(linkedList.contains("123"));
        //检索头不删
        System.out.println(linkedList.element());
        System.out.println(linkedList.peek());
        //检索头并删除
        System.out.println(linkedList.poll());
        System.out.println(linkedList.remove());
        //返回指定的元素
//        System.out.println(linkedList.get(5));
        //从堆栈中弹出列表头 并从列表中删除
        System.out.println(linkedList.pop());
        //替换指定索引出元素
        System.out.println(linkedList.set(3,"傻逼java!"));
//        System.out.println(linkedList1);
        System.out.println(linkedList);
        //转换为数组并进行输出
        Object[] objects = linkedList.toArray();
        for (int i = 0; i <linkedList.size() ; i++) {
            System.out.println(objects[i]);
        }
        System.out.println(linkedList.size());

    }
}

5.Set接口
    * Set接口:
 * 1.无序的 唯一的(不可重复的)
 * 2.使用TreeSet底层的实现是TreeMap,利用红黑数原理实现,也就是数据传入的数据类型要一致
 * 3.设置元素的时候,如果是自定义的对象,会查找对象中的toString方法和hashCode方法,如果没有比较的是地址
 * 4.树中的元素是默认会进行排序操作的,如果是基本数据类型,自动比较,如果是引用数据类型,要自定义比较器
 * 比较器分类:
 *  内部比较器:
 *          1.实现Comparable接口
 *          2.定义在元素类中
 *  外部比较器:
 *          1.定义在当前类中
 *          2.实现Comparator接口,但是要将该比较器传递到集合中(作为参数传入)
 *          注意:
 *          1.当内部比较器和外部比较器同时存在时,执行的是外部比较器
 *          2.外部比较器可以定义成一个工具类,可以复用,而内部比较器只有在存储当前对象的时候可以使用
 *          3.当使用比较器的时候,不会调用equals方法

public class SetDemo {
    public static void main(String[] args) {
       Set set = new HashSet();
        set.add(123);
        set.add("abc");
        set.add(true);
        set.add(100L);
        //如果集合中不包含元素就返回true
        System.out.println(set.isEmpty());
        //删除所有元素
        // set.clear();
        System.out.println(set);
        //迭代器遍历数组
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }


        System.out.println("===============================");
//增强for循环
        for(Object o : set ){
            System.out.println(o);
        }



    Set set = new TreeSet();
    set.add(123);
    set.add("abc");
    set.add(true);
    set.add(100L);
       // 传入数据类型一致(自动使用红黑树算法进行了排序)
        set.add(123);
        set.add(12);
        set.add(25);
        set.add(16);
        set.add("jisj");
        set.add("der");
        set.add("ios");
        set.add("ces");
        System.out.println(set);
        for (Iterator iterator = set.iterator(); iterator.hasNext();){
            System.out.println(iterator.next());
        }

    }


}

6.Iterator迭代器
      所有的集合类都默认实现了Iterable的接口,实现此接口意味着具备了增强for循环的能力,也就是for-each
一般用来遍历数组使用
1.使用普通for循环
2.使用迭代器遍历,也就是使用iterator中的hasNext();和next()方法;
3.增加for循环
        for(Object o : list){
            System.out.println(o);
        }

package com.shun.changyong;
;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(1);
        list.add("abc");
        list.add(1234);
        list.add(true);
        //遍历数组
        for (int i = 0; i <list.size() ; i++) {
            System.out.println(list.get(i));
        }
//使用迭代器遍历数组
        System.out.println("++++++++++++++++++++++++++");
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("============================");
        //增加for循环
        for(Object o : list){
            System.out.println(o);
        }
    }
}

 7.Map映射:<k,v>对,又称键值对
                通过Key找Value可以找到
                通过Value找Key不可以
8.   HashMap和Hashtable的区别:
1.HashMap线程不安全,效率高
2.HashTable线程安全,效率低
3.HashMap中的key和value都可以为空,但是只能允许有一个null值,HashTable都不允许为空
    4.TreeMap, 自行学习API

package com.shun.zuoye;

import java.util.*;

public class MapDemo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<String,Integer>();
            map.put("a",1);
            map.put("d",2);
            map.put("c",3);
            map.put("b",5);
            map.put("e",4);
//        System.out.println(map);
            //判断map中有没有k(映射),有就返回true
        System.out.println(map.containsKey("a"));
        //判断map中有没有v(指定值),有就返回为true
        System.out.println(map.containsValue(1));
        //判断此映射是否为空,为空就返回true
        System.out.println(map.isEmpty());
//        System.out.println(map.remove("a"));
//        System.out.println(map);
        //遍历方式
        //取出key键
        Set<String> key2 = map.keySet();
        for (String key : key2){
            System.out.println(key + "=" +map.get(key));
        }
        System.out.println("******************************************");
        Set<String> key1 = map.keySet();
        for (Iterator<String> iterator = key1.iterator(); iterator.hasNext();){
            String key = iterator.next();
            System.out.println(key+ "=" +map.get(key));
        }
        System.out.println("******************************************");
        Collection<Integer> values = map.values();
        for (Integer value :values){
            System.out.println(value);
        }
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
            for (Map.Entry<String, Integer> entry : entrySet){
                System.out.println(entry.getKey()+ "=" +entry.getValue());
            }

    }
}

顺便说一下数据结构,现在学的虽然不多,但是也得记录一下

9.数据结构

(1)二叉树
    1.左节点的子节点要小于根节点,右子节点要比根节点大
2.一个根节点最多有两个子节点

(2)红黑树
    1.根的节点是黑色
2.每个红色节点的两个子节点是黑色的
3.红黑树牺牲了部分平衡性,以换取 插入\删除 操作时的少量的旋转操作,整体性能要优于AVL数
4.最长的路径不超过最短路径的2倍

(3)AVL平衡树
    1.一个根节点下面有且只有2个子节点
2.任何子节点的两个子树高度最大差别不超过绝对值1

==========================================================

1.集合中的工具类

工具类
    Collections类
        方法为主(查看API)
    Arrays类
         Arrays工具类(详情查看API)
  Arrays提供了数据操作的工具类,包含很多方法
        集合和数组之间的转换
       数组转成list:
1.数组转集合:asList();方法
2.集合转数组:toArray();方法

package com.shun.changyong;

import java.util.*;

/**
 * Collections工具类
 *   在使用二分查找法的前提是先要对集合中的元素进行排序
 */
public class CollectionsDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(12);
        list.add(13);
        list.add(15);
        list.add(10);
        list.add(17);
        //将所有指定元素添加到指定集合中
        Collections.addAll(list,1,2,5);
        System.out.println(list);
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if (o1 > o2){
                    return -1;
                }else if (o1 < o2){
                    return 1;
                }else {
                    return 0;
                }
            }
        });
        System.out.println(list);
        //二分查找法,使用前需要先进行排序
        System.out.println(Collections.binarySearch(list,12));
        //用指定元素替换集合中的所有元素
        Collections.fill(list,123);
        System.out.println(list);
    }

}

2.泛型

泛型
    当做一些集合的统一操作的时候,需要保证集合的类型是统一的,此时需要泛型来进行限制
 *      优点:
 *          1、数据安全
 *          2、获取数据时效率比较高
 *      给集合中的元素设置相同的类型就是泛型的基本需求
 *       使用:
 *          在定义对象的时候,通过<>中设置合理的类型来进行实现
 *  泛型的高阶应用:
 *      1、泛型类
 *          在定义类的时候在类名的后面添加<E,K,V,A,B>,起到占位的作用,类中的方法的返回值类型和属性的类型都可以使用
 *      2、泛型接口
 *          在定义接口的时候,在接口的名称后添加<E,K,V,A,B>,
 *          1、子类在进行实现的时候,可以不填写泛型的类型,此时在创建具体的子类对象的时候才决定使用什么类型
 *          2、子类在实现泛型接口的时候,只在实现父类的接口的时候指定父类的泛型类型即可,此时,测试方法中的泛型类型必须要跟子类保持一致
 *      3、泛型方法
 *          在定义方法的时候,指定方法的返回值和参数是自定义的占位符,可以是类名中的T,也可以是自定义的Q,只不过在使用Q的时候需要使用<
 *          Q>定义在返回值的前面
 *      4、泛型的上限(工作中不用)
 *          如果父类确定了,所有的子类都可以直接使用
 *      5、泛型的下限(工作中不用)
 *          如果子类确定了,子类的所有父类都可以直接传递参数使用
  

public class FanxingDemo {
    public static void main(String[] args) {
        //从JDK1.8之后后面这个<String>可以不用写
        List<String> list = new ArrayList<String>();
//        list.add(1);
//        list.add("abc");
//        list.add(true);
//        list.add(100L);
        list.add("123");
        list.add("abc");
        list.add("true");
        list.add("100L");
        System.out.println(list);
//        //遍历数组
//        for (int i = 0; i <list.size() ; i++) {
//            System.out.println(list.get(i));
//        }
        //迭代器
//        Iterator iterator = list.iterator();
//        while(iterator.hasNext()){
//            System.out.println(iterator.next());
//        }

//        //迭代器
//        for (Iterator iterator = list.iterator();iterator.hasNext();){
//            System.out.println(iterator.next());
//        }
        System.out.println("************************");
增强for循环
//        for (String s : list){
//            System.out.println(s);
//        }
//FanxingClass<String> f = new FanxingClass<String>();
//f.setName("小白");
//f.setA("shie");
//f.show();
        FanxingClass<Dog> f = new FanxingClass<Dog>();
        f.setName("xiaohie");
        System.out.println(f.getName());
        f.setA(new Dog("花花",15));
        System.out.println(f.getA());
        f.set(new Dog("妹妹",50));
        //泛型方法的使用
   FanXingMethod<Dog> f1 =new FanXingMethod<Dog>();
f1.setT(new Dog("小红",15));
f1.show("String");
    }
}

泛型类:

package com.shun.changyong;
//<A>就是一个占位符
public class FanxingClass<A>{
    private String name;
    private A a;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
    public void show(){
        System.out.println(this.a);
        System.out.println(this.name);
    }
    public void set(A a){
        System.out.println("这是set中的A"+a);
    }
    public A get(){
        return a;
    }
}

泛型方法:

package com.shun.changyong;
//<A>就是一个占位符
public class FanxingClass<A>{
    private String name;
    private A a;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
    public void show(){
        System.out.println(this.a);
        System.out.println(this.name);
    }
    public void set(A a){
        System.out.println("这是set中的A"+a);
    }
    public A get(){
        return a;
    }
}

最后在总结一些面试题:方便使用!

1. Vector也是List接口的一个子类实现

 *      1、Vector跟ArrayList一样,底层都是使用数组进行实现的

 *      2、面试经常问区别:

 *          1) ArrayList是非线程安全的,高效率,Vector是线程安全的,低效率

 *          2) ArrayList扩容是每次扩容1.5倍,Vector扩容是每次扩容2倍

2.StringBuffer和StringBuilder的区别?

(1)StringBuffer是线程安全的低效率,由Synchronized实现

(2)StringBuilder是非线程安全的,高效率

3.HasMap和HasTable的区别?

(1)HasTable是线程安全的,低效率,由synchronize实现

(2)HasMap是非线性安全的,高效率

4.ArrayList和LikedList的区别?

(1)底层数据结构不同,ArrayList底层是基于数组实现的,而LinkedList是链表结构实现

(2)使用场景不同:

Q:ArrayList:

~遍历元素和随机访问效率比较高

~插入和删除的效率比较低

Q:LikedList:

~遍历元素和随机访问效率比较低

~插入和删除的效率比较高

(3)都实现了List接口,但是LikedList接口另有实现了一个Deque接口,可以当队列进行使用

PS:队列:FIFO(先进先出)

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值