集合框架和泛型

Collection接口

List接口

Set接口

TreeSet接口

集合与数组之间的转换

Map接口

泛型


概述

  由若干个确定的元素所构成的整体,集合是存储对象的容器,可以存储任意数量,任意类型的对象。存储的是对象的引用值!

  集合的存储长度是可变的,只能存储对象不能存储基本数据类型

1-1  Collection接口

  Collection是单列集合,用来存储一个一个的对象

  Collection和Map接口,都在java.util包下

  Collection是除Map外所有其他集合类的根接口

  Collection提供了两个子接口,List接口和Set接口

 

 

 

package Collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.junit.Test;

public class CollectionTest {
    @Test
    public void test1() {
        Collection coll = new ArrayList<>();
        //add添加元素
        coll.add(123);
        //size集合长度
        System.out.println(coll.size());
        Collection coll1 = new ArrayList<>();
        coll1.add("我是");
        coll1.add(456);
        //addAll 将其他集合元素添加到当前的集合中
        coll.addAll(coll1);
        System.out.println(coll.size());
        //isEmpty 判断当前集合是否为空
        System.out.println(coll.isEmpty());
        //集合---数组  toArray
        Object[] array = coll.toArray();
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
        //数组---集合  调用asList方法
        List<String> asList = Arrays.asList(new String[] {"1","2","3"});
        
    } 
}
----------------------------------------------------------------------------

package Collection;


import java.util.ArrayList;
import java.util.Collection;


public class Test {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add("AA");
//f=方法引用
coll.forEach(System.out::println);
}
}

 

2-1  List接口

  List接口继承自Collection接口,它规定实现它的类存储是有序的,可重复的集合元素,同时提供了实现类ArrayList和LinkedList,Vector

  ArrayList数组形式,连续的存储空间,查询速度快,增删速度慢,可以存储null值和重复的值.

    <!--初始化容器大小是10!!,默认情况下,扩容为原来的1.5倍-->

package List;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

@SuppressWarnings("unused")
public class ArrayListTest {
    public static void main(String[] args) {
        List<String> nameList = new ArrayList<>();
        /*ArrayList<Object> nameList = new ArrayList<>();*/
        //添加元素
        nameList.add("王渝凯");
        nameList.add("张三");
        nameList.add("李四");
        nameList.add("李四");
        //获取元素
        String s1 = nameList.get(0);
        System.out.println(s1);
        //集合中有多少元素
        int size = nameList.size();
        System.out.println(size);
        //移除指定索引的值并返回
        String re = nameList.remove(0);
        System.out.println(re);
        //判断元素是否存在
        boolean con = nameList.contains("王渝凯");
        System.out.println(con);
        //替换指定索引处的值
        @SuppressWarnings("unused")
        String set = nameList.set(0, "王渝凯");
        System.out.println(nameList.get(0));
        //返回元素第一次出现的位置
        int indexOf = nameList.indexOf("李四");
        System.out.println(indexOf);
        //返回元素最后一次出现的位置
        int lastIndexOf = nameList.lastIndexOf("李四");
        System.out.println(lastIndexOf);
        //判断集合是否为空
        boolean empty = nameList.isEmpty();
        System.out.println(empty);
        //转换成数组
        /*Object [] array =  nameList.toArray();
        for (Object str : array) {
            System.out.println(str);
        }*/
        /*String[] array2 = nameList.toArray(new String [0]);
        for (String str : array2) {
            System.out.println(str);
        }*/
        //清除集合中的元素
        /*nameList.clear();*/
        System.out.println("------------");
        //获取元素中的所有元素内容
        //1.使用for循环
        for (int i = 0; i < nameList.size(); i++) {
            System.out.println(nameList.get(i));
        }
        //2.使用foreach循环
        for (Object str : nameList) {
            System.out.println(str);
        }
        //3.使用迭代器
        @SuppressWarnings("unused")
        Iterator<String> it = nameList.iterator();
        while (it.hasNext()) {//判断有没有下一个元素
            String next = it.next();//获取下一个元素
            System.out.println(next);
        }
    }
}

  LinkedList双向链表,不连续的存储空间,增删速度快,查询速度慢,可以存储null值和重复的值 

package List;

import java.util.Iterator;
import java.util.LinkedList;

public class LinkedListTest {
    public static void main(String[] args) {
        //创建方式
        LinkedList<Object> linkedList = new LinkedList<>();
        //向集合中添加元素
        linkedList.add("张三");
        linkedList.add("李四");
        linkedList.add("王五");
        linkedList.add("赵六");
        linkedList.add("田七");
        //迭代集合中的元素
        Iterator<Object> iterator = linkedList.iterator();
        while(iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }
        //将指定元素添加到集合的开头
        linkedList.addFirst("陈伟霆");
        //将指定元素添加到集合的末尾
        linkedList.addLast("权志龙");
        Iterator<Object> it = linkedList.iterator();
        while(it.hasNext()) {
            Object next = it.next();
            System.out.println(next);
        }
        //获取集合中的第一个元素
        System.out.println(linkedList.getFirst());
        //获取集合中最后一个元素
        System.out.println(linkedList.getLast());
        //删除集合中的第一个元素
        System.out.println(linkedList.removeFirst());
        //删除集合中的最后一个元素
        System.out.println(linkedList.removeLast());
    }
}

  Voctor接口:

    作为List接口的古老实现类:线程安全的,但是效率低,底层使用Object[]

3-1  Set接口

  Set接口继承自Collection接口,他的存储是无序的,唯一的元素(不允许重复)

  HashSet类实现了Set接口,是基于HashMap实现,存储不重复无序的

无序性:不等于随机性,
 * 以HashSet为例:存储的数据在底层数组中并非按照数组索引的顺序添加的。是根据数据的Hash值决定的
 * 不可重复性:保证添加的元素按照equals()判断时,不能反悔true,即:相同的元素只能添加一个
 * 二:添加过程以HashSet为例:
 * 我们向HashSet中添加元素a,首先调用他所在类的hashCode()方法,计算它的哈希值
	 * 此哈希值通过某种算法计算出在HashSet底层数组中的存放位置(索引位置)
 	* 判断数组此位之上是否已经有元素, 如果没有则直接添加成功,如果此位置上有其他元素,
 * 首先比较他们的哈希值,如果不相同(链表形式)则直接添加成功(七上八下),如果相同,那么则需要调用他的equals方法,如果方法返回true那么添加失败,反之添加成功
    要求:向set中添加元素,其所在的类一定要重写HashCode()和equals();
    重写的两个方法尽可能保持一致性

  

public static void main(String[] args) {
        //创建方式
        HashSet<String> set = new HashSet<>();
        //添加元素
        set.add("张三");
        set.add("李四");
        set.add("王五");
        set.add("王五");
        System.out.println(set.size());
        //遍历
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String next =  it.next();
            System.out.println(next);
        }
    }

  LinkedList

LinkedList作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,
 * 记录此时数据的前一个数据和后一个数据
 * 优点:对于频繁的遍历操作,效率高于HashSet
 
import java.util.LinkedHashSet;
/*
 * 作为HashSet的子类出现的,遍历其内部数据时可以按照添加的顺序去遍历
 */
public class LinkedHashSetTest {
	public static void main(String[] args) {
		LinkedHashSet<Object> set = new LinkedHashSet<>();
		set.add("AA");
		System.out.println(set);
	}
}

4-1  TreeSet

/*
 * 1.向TreeSet中添加的数据要求同一个类的对象
 * 2.向当中添加的元素可以按照对象的指定属性进行排序
 *         两种排序方式:自然排序和定制排序
 * 自然排序:比较两个对象是否相同的标准为:compareTo(),不在是equals();
     定制排序:比较两个对象是否相同的标准为:compare(),不在是equals();
 */
package set;

import java.util.*;

import org.junit.Test;

public class TreeSetTest {
    @Test
    public void test() {
        TreeSet set = new TreeSet();
        //失败:   不能添加不同类的对向
        /*set.add(123);
        set.add(456);
        set.add("AA");
        set.add("BB");*/
        /*System.out.println();
        set.add(34);
        set.add(33);
        set.add(22);
        set.add(66);*/
        //使用迭代器遍历
        /*Iterator it2 = set.iterator();
        Iterator it = it2;
        while (it.hasNext()) {
            Object obj = it.next();
            System.out.println(obj);
        }*/
        System.out.println("-------------");
        //对象比较从大到小
        set.add(new User("tom",18));
        set.add(new User("jerry",12));
        set.add(new User("jim",22));
        set.add(new User("lili",16));
        set.add(new User("lili",56));
        
        Iterator it2 = set.iterator();
        Iterator it = it2;
        while (it.hasNext()) {
            Object obj = it.next();
            System.out.println(obj);
        }
    }
}
User类:
    package set;

public class User implements Comparable {
    private String name;
    private int 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;
    }
    public User() {
        super();
    }
    public User(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    //按照姓名从小到大排序,其次年龄按照从大到小
    @Override
    public int compareTo(Object o) {
        if(o instanceof User) {
            User u = (User)o;
            /*return -this.name.compareTo(u.name);*/
            int compare =  -this.name.compareTo(u.name);
            if(compare != 0) {
                return compare;
            }else {
                return Integer.compare(this.age, u.age);
            }
        }else {
            throw new RuntimeException("输入的类型不匹配");
        }
    }
    
}

5-1  集合与数组之间的转换

package Collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.junit.Test;

public class CollectionTest {
    @Test
    public void test1() {
        Collection coll = new ArrayList<>();
        //add添加元素
        coll.add(123);
        //size集合长度
        System.out.println(coll.size());
        Collection coll1 = new ArrayList<>();
        coll1.add("我是");
        coll1.add(456);
        //addAll 将其他集合元素添加到当前的集合中
        coll.addAll(coll1);
        System.out.println(coll.size());
        //isEmpty 判断当前集合是否为空
        System.out.println(coll.isEmpty());
        //集合---数组  toArray
        Object[] array = coll.toArray();
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
        //数组---集合  调用asList方法
        List<String> asList = Arrays.asList(new String[] {"1","2","3"});
        
    } 
}

6-1  Map接口

概述:

   Map接口是一个根接口,是一个双列集合,它存储的是键-值对(key - value),其中key不允许重复,value允许重复 

  Hashtable:古老的实现类,线程安全的,效率低,不可以存储null的key或null的value

  LinkedHashMap:保证在遍历元素时,可以按照添加顺序遍历,(底层添加了指针,指向前一个和后一个元素),对于频繁的遍历操作他的效率高于HashMap

  TreeMap:可以按照添加的kv进行排序实现排序遍历(按照key排序的)

  HashMap类实现了Map接口,存储的是无序的键-值对,效率高,可以存储null的key和null的value(实现原理:数组 + 链表 + 红黑树)

    1.HashMap的key是用set集合来存放的需要重写hashCode和equals方法

    2.HashMap是线程不安全的

    3.HashMap中元素的位置是不定时更新的,即元素位置不固定

  HashMap的底层实现原理

  实例化过程:HashMap map = new HashMap();

  -----可能执行过多次put----

    map.put(key1,value1)

    在实例化以后,底层创建了长度是16的一维数组Node(Entry[] table);

    首先调用key1所在类的HashCode()计算它的哈希值,得到它的所在位置,此位置为空添加成功如果此位置不为空,比较他们的哈希值,如果哈希值不同,添加成功,反之调用equals()方法,如果返回false添加成功,反之value替换相同key的value(覆盖)

    扩容:默认的扩容两倍,并将原来的数据发到里面

    <!--当元素个数超过8并且数组长度大于64时使用红黑树存储-->

package Map;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.*;

public class HashMapTest {
    public static void main(String[] args) {
        //创建方式
        HashMap<String, String> map= new HashMap<String, String>();
        //添加元素
        map.put("name", "王渝凯");
        map.put("age", "22");
        map.put("gender", "男");
        map.put("address", "河南省林州市");
        //获取指定的key的值
        System.out.println(map.get("name"));
        //看是否包含指定的键
        boolean con = map.containsKey("name");
        System.out.println(con);
        //看是否包含指定的值
        boolean con2 = map.containsValue("王渝");
        System.out.println(con2);
        Set<String> keySet = map.keySet();
        System.out.println(keySet);
        //遍历--kv当做一个整体来看
        Iterator<Entry<String, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
            //通过get方法获取kv相对应的值
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + ":" + value);
        }
        System.out.println("-----------");
        //2.key作为set集合
        Iterator<String> it2 = map.keySet().iterator();
        while (it2.hasNext()) {
            String key = it2.next();
            String value = map.get(key);
            System.out.println(value);
            System.out.println(key);
        }
        System.out.println("-----------");
        //3.value作为set集合
        Iterator<String> it3 = map.values().iterator();
        while (it3.hasNext()) {
            String value = it3.next();
            System.out.println(value);
        }
    }        
}

7-1  泛型(这个我目前学到的只有简单的这些)

概述:

泛型,即参数化类型。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也可以自定义参数形式。然后在调用时传入具体的类型。(吧类型明确的工作推迟到创建对象或调用方法的时候去明确特殊的类型)

public static <T> void show(T t) {
        System.out.println(t);
    }

 

posted @ 2021-02-21 23:46  大可耐啊  阅读(101)  评论(0编辑  收藏  举报