1.集合框架的概念

        Java集合框架(Java Collections Framework简称JCF)是为表示和操作集合,而规定的一种统一的标准的体系结构。集合框架包含三大块内容:对外的接口、接口的实现和对集合运算的算法。数组和集合的区别:数组是定长的,集合是不定长的。

集合和数组的区别

数组和集合相比,数组的缺点是它长度是固定的,没有办法动态扩展。

而集合存储数据时是没有长度限制的,是可以动态扩展的。集合容器因为内部的数据结构不同,有多种不同的容器对象。这些容器对象不断的向上抽取,就形成了集合框架。

2.Collection集合

Collection接口是单值集合的顶层接口,它的继承关系如下。

        2.1 Collection集合默认可以存储任何类型的元素

        2.2 Collection可以重复添加,并且可以存储空值null

        2.3 不能根据下标获取单个元素

        2.4 Collection的方法使用
 

 Collection coll = new ArrayList();//定义Collection接口变量,指向其实现对象Arraylist
        coll.add("a");//添加String类型的a
        coll.add(5);//添加整形的5
        coll.add('b');//添加char类型的b
        Collection colls = new ArrayList(2);
        colls.add(2);
        colls.add(3);
        coll.addAll(colls);
        System.out.println(coll);
        boolean b = coll.containsAll(colls);//判断coll中是否包含colls中的所有元素
        System.out.println(b);
        int size = coll.size();//获取coll的长度
        System.out.println(size);
        coll.remove(5);//删除2这个元素
        coll.removeAll(colls);//批量删除coll中的colls的元素
        System.out.println(coll);
        boolean empty = coll.isEmpty();//判断coll是否为空
 
        System.out.println(empty);
        coll.clear();//清除coll中的所有元素
        boolean empty1 = coll.isEmpty();
        System.out.println(empty1);

3.List

       

        3.1 List集合是有序集合: 数据的添加和存储次序一致, List集合可以存储重复的数据, List集合中的数据可以通过下标访问

        3.2 ArrayList实现类的用法

特点:

  • 实现了List接口
  • 可以动态扩容(我们只管存,长度不够,底层会自动的扩容)
  • 通过下标可以快速访问数据
  • 查找快,插入删除慢
  • ArrayList底层是数组,对数组做了封装
  • 可以存储任意类型的数据,包括null
  • 数据按照存储次序排列
  • 数据可以重复
  • 多线程访问时不安全

                3.2.1 实现了list接口,可以动态扩展,可以使用下标进行访问数据,查找较快,删除和插入较慢,ArrayList的底层就是数组,对数组进行了封装,多线程访问的时候是不安全的。
 

 List list = new ArrayList(5);//创建长度为五的Arraylist对象
        list.add("a");//在集合中添加一个String类型的a
        list.add(5);//在集合中添加一个整形的数字5
        list.add('a');//添加一个char类型的a
        list.add(new Date());//添加一个Date类型的数据
        list.add("a");//可以添加重复的数据
        //当添加的内容超过数组的长度后会自动扩容
        list.add("菠萝是种好水果");
        System.out.println(list);//输出集合的内容
        list.set(3,"好水果");
        list.remove(new Date());//移除集合中的Date数据
        System.out.println(list);
        list.remove(1);//移除下标为1的内容
        List listTwo = new ArrayList(2);
        listTwo.add("凤梨");
        listTwo.add(1,"哈哈哈哈");
        list.addAll(listTwo);//将集合listTwo中的所有内容添加到list集合中
        System.out.println(list);
        System.out.println(list.contains("菠萝是种好水果"));//查找集合中是否存在“菠萝是种好水果”
        System.out.println(list.containsAll(listTwo));
        list.get(2);//获取下标为2的内容
        list.indexOf("a");//查找a首次出现的位置
        System.out.println(list.size());//输出集合的长度
        System.out.println(list.isEmpty());//判断集合是否为空
        int i = list.hashCode();//返回list的哈希码值
        System.out.println(i);
          list.clear();//清空集合
       

 3.3LinedList和Vector实现类的用法

                LinkedList: 具有List的特征,底层以链表结构实现,可以进行头尾元素的添加删除

                Vetor: 与ArrayList功能一致,在多线程环境下,比ArrayList安全。查询效率高,增加删除效率低,性能比较低。

              


LinkedList linkedList=new LinkedList();
        linkedList.add("a");//添加字符型的a
        linkedList.add(5);//添加整型数据
        linkedList.add(new Date());//添加时间类型数据
        linkedList.addFirst(1);//在头部添加数据
        linkedList.addLast("尾");//在尾部添加数据
        linkedList.set(2,"hello");//在下标为2的地方插入元素
        System.out.println(linkedList.get(2));//获取下标为2的元素内容
        linkedList.getFirst();//获取第一个数据 即linkedlist【0】
        linkedList.getLast();//获取最后一个元素的内容
        LinkedList linked = new LinkedList(); //LinkedList不能指定长度
        linked.add(11);
        linked.add(10);
        linkedList.addAll(linked);//批量添加元素 即添加linked中是所有元素
        System.out.println(linkedList);
        linkedList.remove(2);//删除下标为2的元素的内容
        System.out.println(linkedList);
        System.out.println(linked);
        linkedList.addAll(0,linked);//在下标为2的地方放批量插入数据
        System.out.println(linkedList);
        linkedList.removeFirst();//删除头部元素
        linkedList.removeLast();//删除尾部元素
        System.out.println(linkedList);

4 Set

Set接口特点

  • Set接口是无序的
  • Set接口中的数据不允许重复
  • Set接口无法通过下标访问数据
  • 查找慢,插入删除快(底层数据结构是哈希表和红黑树)
  • Set集合使用equals()和hashCode()方法实现元素去重

        4.1.set是无序且不能重复的,他是一个接口,它包含HashSet和TreeSet两个部分。底层逻辑是hashMap

        4.2.HashSet的使用方法如下

HashSet特点:

  • HashSet是Set接口的实现类
  • 线程不安全
 HashSet hashSet = new HashSet();//默认的长度是16
 
        HashSet hashSet1 = new HashSet(5);//可以指定长度
 
        HashSet hashSet2 = new HashSet(15,0.7f);
        //其中15表示长度,0.7表示负载因子,即当资源使用达到70%的时候会自动扩容
        hashSet.add(1);//添加数字1
        hashSet.add("A");
        hashSet.add("B");
        hashSet.add('A');
        hashSet.add("A");
        System.out.println(hashSet);//当添加的内容有重复时会自动舍弃,因为hashset是不可重复的,根据输出来看hashSet是无序的
        hashSet1.add("喜洋洋");
        hashSet1.add("海绵宝宝");
        hashSet1.add("暖洋洋");
        hashSet.addAll(hashSet1);//批量添加元素,即将hashSet1中的所有元素都添加到hashSet中,
        System.out.println(hashSet);
        int size = hashSet.size();//获取长度
        System.out.println(size);
        boolean a = hashSet.contains("A");//判断A是否在hashSet集合中
        System.out.println(a);
        boolean empty = hashSet.isEmpty();//判断是否为空
        System.out.println(empty);
        hashSet.remove("灰太狼");//移除孙传芳
        System.out.println(hashSet);
 
        //foreach方式遍历hashSet集合
 
        for (Object o:hashSet) {
            System.out.print(o+"\t");
        }
        System.out.println("\n"+"——————————————————————————我是分割线————————————————————————");
        //使用迭代器遍历
        Iterator iterator = hashSet.iterator();//获取迭代器对象
        while (iterator.hasNext()){//判断指针是否能够移动
 
            System.out.print(iterator.next()+"\t");//输出当前指针所指的元素.next表示获取当前指针所指的元素
        }
       

HashSet避免对象重复的规则:

1)如果对象的hashCode值不同,则不用判断equals方法,就直接存到HashSet中。

2)如果对象的hashCode值相同,需要用equals方法进行比较,如果结果为true,则视为相同元素,不存储。如果结果为false,视为不同元素,进行存储。

 注意:如果对象元素要存储到HashSet中,必须覆盖hashCode方法和equals方法。才能保证从对象中的内容的角度保证唯一。

TreesSet特点:

  • 有序
  • 不重复
  • 添加、删除、判断元素存在性效率比较高
  • 线程不安全

TreeSet对元素进行排序的方式:

1) 如果是基本数据类型和String类型,无需其它操作,可以直接进行排序。

2) 对象类型元素排序,需要实现Comparable接口,并覆盖其compareTo方法。

3) 自己定义实现了Comparator接口的排序类,并将其传给TreeSet,实现自定义的排序规则

4.3.TreeSet的底层逻辑是二叉树,TreeSet可以实现有序集合,但是有序需要通过比较器实现

4.4.TreeSet的使用方法:和hashSet一模一样

TreeSet 基于TreeMap 实现。TreeSet可以实现有序集合,但是有序性需要通过比较器实现。

 TreeSet treeSet = new TreeSet();
        treeSet.add("A");
        treeSet.add("B");
        treeSet.add("C");
        treeSet.add("D");//添加元素
        TreeSet treeSet1 = new TreeSet();
        treeSet1.add("慢走");
        treeSet1.add("欢迎下次再来");
        treeSet.addAll(treeSet1);//批量添加元素
        System.out.println(treeSet);
        System.out.println(treeSet.size());//输出treeSet的长度
        treeSet.remove("D");//删除D
       

 4.5比较器的实现方法

当添加对象类型的数据时需要指定比较器

public class Test03 {
    public static void main(String[] args) {
        TreeSet treeSet=new TreeSet();
        treeSet.add(new Student("张三",15));
        treeSet.add(new Student("李四",16));
        treeSet.add(new Student("王五",18));
        treeSet.add(new Student("麻叶子",15));
        System.out.println(treeSet);
    }
}
class Student{
    String name;
    int age;
 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public Student() {
    }
 
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }

}

 Student类需要实现Comparable接口 其次重写compareTo方法

@Override
    public int compareTo(Object o) {
        Student student=(Student) o;
 
        if(this.age>student.age){
            return 1;
        }
        if(this.age<student.age){
            return -1;
        }
        return 0;
 
    }

在创建TreeSet时 为其指定排序得规则

TreeSet treeSet=new TreeSet(); 但是在创建对象时 并没有为
其指定排序得规则,那么就要求该集合得元素有排序规则。 如果元素得类
已经创建完成,不能修改该类得源码,这时我们又想把该类得对象放入得
TreeSet容器中。 这时就需要你在创建TreeSet时指定排序得规则。

public class MyComparator implements Comparator {
 //需要比对得两个对象
 @Override
 public int compare(Object o1, Object o2) {
   Student s1= (Student) o1;
   Student s2= (Student) o2;
   if(s1.getAge()>s2.getAge()){
     return 1;
   }else if(s1.getAge()<s2.getAge()){
     return -1;
   }else {
     return 0;
   }
 }
}
public class Demo01 {
 public static void main(String[] args) {
   //Comparator<? super E> comparator
   //为TreeSet容器指定了排序规则
   TreeSet treeSet=new TreeSet(new
MyComparator());
   treeSet.add(new Student(18,"王亚波"));
   treeSet.add(new Student(17,"潘世浩"));
   treeSet.add(new Student(19,"刘晓东"));
   treeSet.add(new Student(19,"娄明阳"));
   System.out.println(treeSet);
 }
} 

5.Map 属于键值对模式

map中得每个元素属于键值对模式。 如果往map中添加元素时 需要添加key
和 value. 它也属于一个接口,该接口常见得实现类有: HashMap.

(1)如何创建Map对象

//默认初始化大小为16 负载因子为0.75
    Map map=new HashMap();
    //初始化大小
    Map map2=new HashMap(16);
    //初始化大小 负载因子
    Map map3=new HashMap(16,0.78f);

 (2)添加操作

//默认初始化大小为16 负载因子为0.75
    Map map=new HashMap();
    //添加操作 key: name   value: 高景霞
    map.put("name","高景霞"); //注意: 要求map得key必
须唯一。
    map.put("age",18);
    map.put("name","李赛"); //因为key不能重复,所以后
者会把前者覆盖
    Map m1=new HashMap();
    m1.put("k1","v1");
    m1.put("k2","v2");
    map.putAll(m1); //把m1中得每个元素 添加到map中
    map.putIfAbsent("age",28) ;//如果指定得key存在,
则不放入map中,如果不存在则放入map中
    System.out.println(map);

 (3)删除操作

 //删除操作
    map.remove("age2");//根据指定得key移除元素
    System.out.println(map);
 map.clear(); //清空map容器
    System.out.println(map);

 (4)修改操作

//修改操作
   map.replace("name","张杰");//替换元素
   System.out.println(map);

 (5)查询

public static void main(String[] args) {
    Map map=new HashMap();
    map.put("k1","v1");
    map.put("k4","v4");
    map.put("k2","v2");
    map.put("k3","v3");
    //查询操作
    boolean f = map.containsKey("k5");//判断map是否
存在指定得key
    Object v = map.get("k5"); //根据指定的key获取对应
得value值
    System.out.println(v);
    Set keys = map.keySet();//返回该map中所有得key
    System.out.println(keys);
    //遍历map.
    for(Object k:keys){
      Object value= map.get(k);//

    
 System.out.println(k+"================>"+value);
 }
}

6.泛型

(1)什么是泛型

 泛型就是限制我们得数据类型。

语法:

Plain Text

List<E>:E类型约束

Set<E> : E类型约束

Map<K,V>:K,V类型约束

(2)为什么使用泛型?
我们原来在定义集合时,是如下得定义方式:
   

public static void main(String[] args) {
    List<String> list=new ArrayList<>();//这里就限制
了集合中每个元素得类型。
    list.add("java01");
    list.add("hello"); //因为集合中只能添加String类型
    list.add("world"); //因为集合中只能添加String类型
    String s = list.get(0); //在获取元素时 默认就是相应
得数据类型 而无需在进行转换
    //<K,V>:K:表示键得泛型 V:表示值得泛型
    HashMap<String,Integer> map=new HashMap<>();
    map.put("name",15);
    map.put("age",25);
    Set<String> keys = map.keySet();
}

 

(3)如何使用泛型

List<类型> list=new ArrayList<类型>(); 只能在该集合中存储指定得类型

public static void main(String[] args) {
    List<String> list=new ArrayList<>();//这里就限制
了集合中每个元素得类型。
    list.add("java01");
    list.add("hello"); //因为集合中只能添加String类型
    list.add("world"); //因为集合中只能添加String类型
    String s = list.get(0); //在获取元素时 默认就是相应
得数据类型 而无需在进行转换
    //<K,V>:K:表示键得泛型 V:表示值得泛型
    HashMap<String,Integer> map=new HashMap<>();
    map.put("name",15);
    map.put("age",25);
    Set<String> keys = map.keySet();
}

(4)能否自己定义泛型:可以

public class 类名<标识,标识....> {
  标识 变量名;
 
  public 标识 方法名(){
   
  }
 
  public void 方法名(标识 参数名){
 
 
  }
  .........
}

定义坐标类

public class Test03 {
  public static void main(String[] args) {
    //在创建泛型类对象时没有指定相应得泛型类型。则默认为
Object类型
    Point p1=new Point();
    p1.setX(15);
    p1.setX("北纬50度");
    //这里得泛型必须都是对象类型
    Point<Integer> p2=new Point<Integer>() ;
    p2.setX(25);
    p2.setY(65);
    Integer x = p2.getX();
    Integer y = p2.getY();
    p2.show();
    Point<String> p3=new Point<>();
 }
}
class Point<T>{
  private T x;
  private T y;
  public void show(){
    System.out.println("x坐标为:"+x+";y坐标为:"+y);
  }
  public T getX() {
    return x;
 }
  public void setX(T x) {
    this.x = x;
 }
  public T getY() {
    return y;
 }
  public void setY(T y) {
    this.y = y;
}
}