Java集合框架 && 泛型例子

集合框架介绍及例子

package lxg.JHDemo;

import com.lxg.JHDemo.Dog;
import com.lxg.JHDemo.Fanxing;
import com.lxg.JHDemo.Person;

import java.util.*;

/**
 * @author lxg
 * @description 集合框架测试类
 * @date 2021/9/4
 *
 *集合框架:
 *   Collection:存放的是单一值
 *        特点:
 *           1.可以存放不同类型的数据,数组只能存放固定类型的数据
 *           2.当使用ArrayList子类实现的时候,初始化长度是10,当长度不够的时候,会自动进行扩容操作,每一次扩容都会为原来的1.5倍
 *       方法:
 *          add: 要求必须传入的参数是Object对象,因此,当写入基本数据类型的时候,包含了自动拆箱和自动装箱的过程
 *          addAll:添加另一个集合的元素到此集合中
 *
 *          clean:只是清空集合中的元素,但是此集合对象没有被回收
 *          remove:删除指定元素
 *          removeAll:删除集合元素
 *
 *          contains:判断集合中是否包含指定的元素
 *          containsAll:判断此集合中是否包含另外一个集合
 *
 *
 *----接口 Collection:
 *     不唯一,无序
 *
 *   1.接口 list
 *     不唯一,有序
 *     api:
 *       add:添加元素
 *       addAll:将另一个list的数据添加到此list
 *       clean:清空list
 *       contains:判断是否包含指定元素
 *       containsAll:判断是否包含某list
 *       copyof:复制该list
 *       equals:比较两list是否相等
 *       hashCode:发牛哈希值
 *       indexOf:返回指定对象的位置
 *       isEmpty:判断是否为空
 *       iterater:返回一个遍历器
 *       size:返回list大小
 *       toArray:将list转化为数组
 *       set:更改指定位置上的元素
 *       get:获取指定位置上的元素
 *
 *     List的接口实现:
 *         ArrayList:
 *            -  实现了长度可变的数组,底层使用数组实现的
 *               可动态调整容量
 *               元素可以为null
 *               不同步、非线程安全、效率高
 *               查询块、增删慢
 *               占用空间更小,对比 LinkedList,不用占用额外空间维护链表结构
 *               每次扩容1.5倍
 *
 *            - 优点:遍历数组和随机访问效率高
 *            - 缺点:添加和删除需要移动大量元素,效率比较低,按照元素内容查询效率也低
 *
 *            api:
 *
 *
 *         LinkedList:
 *            - 采用链表的方式实现
 *            - 优点:插入、删除元素效率较高,只需要修改链表节点的指针位置,不需要移动元素
 *            - 缺点:遍历和随机访问效率低下
 *
 *            api:
 *              	add​(int index, E element)
 *              	add​(E e)
 *              	addAll​(int index, Collection<? extends E> c)
 *              	addAll​(Collection<? extends E> c)
 *                 	addFirst:添加头
 *                 	addLast:添加尾
 *                 	offerFirst 1.6版本之后的添加头
 *                 	offerLast:添加尾
 *                 	removeFirst:删除头
 *                 	removeLast:删除尾
 *                 	pollFirst:
 *                 	pollLast:
 *                 	getFirst:获取头
 *                 	getLast:获取尾巴
 *                 	peekFirst:
 *                 	peekLast:
 *
 *         Vector:
 *             - 底层使用数组实现
 *             - 相比于ArrayList,是线程安全的,效率低
 *             - 每次扩容2倍
 *
 *   2.接口 set
 *     - 唯一,无序(存入和取处的顺序不一致)
 *     - 操作数据的方法与List类似,Set接口不存在get方法
 *     - set不可以通过下标来获取元素,因为元素无序
 *     - 设置元素的时候,如果是自定义对象时,会自动查找对象中的equals和hashcode方法,如果没有,设置的是地址,所以需要比较的话,
 *       需要重写equals和hashcode
 *     - 树在操作元素的时候默认有排序操作的,如果是基本数据类型,自动比较,如果是引用类型,需要自定义比较器
 *          比较器分类:
 *             内部比较器:
 *                 定义在元素的类中,通过实现Comparable接口来进行实现。
 *             外部比较器:
 *                 定义在当前类中,通过实现Comparator接口来实现,但是要将该比较器传递到集合中
 *                 TreeSet treeSet = new TreeSet(new Test());
 *             注意:外部比较器可以定义成一个工具类,此时如果需要比较的规则一致的话,可以重复使用
 *                  内部比较器只有在使用此对象的比较时才能使用
 *                  如果两者同时存在,使用外部比较器
 *                  当使用比较器的时候,不适用equals方法
 *
 *
 *     set接口的实现:
 *        HashSet:
 *           - 底层是HashMap,采用HashTable哈希表存储结构
 *           - 优点: 添加速度快、查询速度快、删除速度快
 *           - 缺点: 无序
 *
 *           - LinkedHashSet:
 *                -- 采用哈希表存储结构,同时使用链表维护次序
 *                -- 有序(添加顺序)
 *
 *           - HashSet存入值相同的不同引用对象时,能够存入,如何解决不重复元素问题?
 *             -- 解决方法:重写equals方法和hashCode方法
 *
 *           - HashSet是如何保证元素的唯一性的?
 *             -- 通过两个方法来完成的,如果元素的hashCode相同,才会判断equals是否为true
 *                如果元素的hashCode不同,不会调用equals方法
 *
 *        TreeSet:
 *           - 底层是treeMap,采用二叉树(红黑树)的存储结构
 *           - 优点: 有序(排序后的升序),查询速度比List块
 *           - 缺点: 查询速度没有HashSet块
 *
 *
 *
 * ----接口Iterator:
 *    所有实现了Collection接口的的容器都有一个iterator方法,用以返回一个实现了Iterator接口的对象。
 *    Iterator对象承做迭代器,用以方便实现对容器内元素的遍历操作
 *    Iterator定义了如下方法:
 *       hasNext():判断是否还有元素没有被遍历
 *       next():返回游标当前位置的元素并将游标移动到下一个位置。
 *       remove:删除游标左面的元素,在执行next 之后改操作只能执行一次
 *
 *    在Java代码中包含三种循环
 *        do...while
 *        while
 *        for
 *
 *     还有一种增强for循环,可以简化循环的编写
 *      for (Object i:arrayList) {
 *             System.out.println(i);
 *         }
 *
 *    所有的集合类都默认是实现了Iterable接口,实现此接口意味着具备了增强for循环的能力,也就是for-each
 *    增强for循环本质上使用的也是iterator的功能
 *       方法:
 *          iterator()
 *          foreach()
 *    在iterator的方法中,要求返回一个Iterator的接口子类实例对象
 *      此接口中包含了
 *         hasNext()
 *         next()
 *     在使用iterator进行迭代的过程中,如果删除其中某个元素会报错,并发操作异常,因此,如果遍历的同时需要修改元素,建议使用ListIterator()
 *     ListIterator提供了向前和向后两种遍历方式
 *         始终是通过cursor和lastret的指针来获取元素值及向下的遍历索引
 *         当使用向前遍历的时候必须保证指针在迭代器的结果,否者无法获取结果值
 *
 *
 * ---- 接口 Map:
 *   - key-value映射
 *
 *   基本api操作:
 *      put(k,v):添加
 *
 *   实现子类:
 *   1.HashMap
 *     - 数组-链表(1.7) 数组-链表-红黑树(1.8)
 *     - key无序 唯一  可为空(set)
 *     - Value无序 不唯一(Collection)
 *
 *     - HashMap跟HashTable的区别?
 *       -- 1.hashMap线程不安全,效率高,hashTable线程安全,效率低
 *       -- 2.hashmap中key和value都可以为空,hashtable不允许为空
 *
 *     - hashmap初始值为2的N次幂
 *
 *   2.LinkedMap
 *     - 链表
 *     - 有序的HashMap 速度快
 *
 *   3.TreeMap
 *     -  红黑树
 *     - 有序 速度没有hash块
 *     -
 *
 *
 */
public class Test implements Comparator<Person>{


    /*Map*/
    @org.junit.Test
    public void mapTest(){
        Map<String,Integer> map = new HashMap<>();
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        map.put("d",1);
        map.put("e",5);
        System.out.println(map);

        /*常用api*/
        map.put("f",8);
        map.isEmpty();
        map.clear();
        map.size();
        map.containsKey("a");
        map.containsValue(3);
        map.get("a");
        map.remove("a");

        //遍历操作
        //方式一
        Set<String> keys = map.keySet();
        for (String key:keys) {
            System.out.println(key+":"+map.get(key));
        }
        for(Iterator iterator = keys.iterator();iterator.hasNext();){
            System.out.println(map.get(iterator.next()));
        }


        //方式二
        Collection<Integer> values = map.values();
        for(Integer value:values){
            System.out.println(value);
        }
        /*for(Iterator iterator=values.iterator();iterator.hasNext();){
            System.out.println(iterator.next());
        }*/

        /*
        * Map.Entry:表示的是k-v组合的一组映射关系,key和value成组出现
        * */
        Set<Map.Entry<String,Integer>> entries = map.entrySet();
        Iterator iterator = entries.iterator();
        while(iterator.hasNext()){
            Map.Entry<String,Integer> next = (Map.Entry<String, Integer>) iterator.next();
            System.out.println(next.getKey()+"--"+next.getValue());
        }

    }



    /*泛型:
    * 当做一些集合的同一操作的时候,需要保证集合的元素类型时统一的,此时需要泛型来限制
    * - 优点:
    *    1.数据安全
    *    2.获取数据时效率比较高
    *
    * - 给集合中的元素设置相同的类型就是泛型的基本需求
    *   使用:
    *     在定义对象的时候,通过<>中设置合理的类来进行实现
    *
    * - 泛型的高级应用:
    *   1.泛型类
    *     在定义类的时候,在类名的后面添加<E、K、V、A、B>等,起到占位的作用,类中的方法的返回值类型和属性都可以使用
    *   2.泛型接口
    *     在定义接口的时候,在接口名后面添加<E、K、V、A、B>等,起到占位的作用;
    *     1.子类在进行实现的时候,可以不填写泛型的类型,此时在创建具体的子类对象的时候才决定使用什么类型
    *     2.子类在实现泛型接口的时候,只在实现父类的接口的时候指定父类的泛型类型即可,此时,测试方法中的泛型类型必须跟子类泛型类型一致
    *   3.泛型方法
    *     在定义方法的时候,指定方法的参数或返回值是泛型是自定义的占位符,可以是类名中的T,也可以是自定义的Q,只不过在使用Q的时候,需要使用<Q>
          定义在返回值前面。
    *   4.泛型的上限
    *   5.泛型的下限
    *
    *
    * */
    @org.junit.Test
    public void fxTest(){
       /*存在问题演示*/
        List list = new ArrayList();
        list.add(1);
        list.add("abc");
        list.add(true);
        list.add(new Person("zhangsan",18));
        System.out.println(list);

        //要求:打印list中person的名字
        //使用for循环
        for (int i =0;i<list.size();i++){
            System.out.println(list.get(i));
        }

        //for-each,问题:很难取出元素中的person类型
        for (Object o:list) {

            System.out.println(o);
        }

        /*------------------------------------------------------*/
        //测试泛型类
        //传String类型
        Fanxing<String> fanxing = new Fanxing<>();
        fanxing.setA("zhangsan");
        fanxing.setId(1);
        fanxing.show();

        //传Person类
        Fanxing<Person> fanxing1 = new Fanxing<>();
        fanxing1.setA(new Person("lisi",20));
        fanxing1.setId(2);
        fanxing1.show();

        //泛型接口

    }

    /*重写外部比较器,需要实现Comparator接口*/
    @Override
    public int compare(Person o1, Person o2) {
        if(o1.getAge()>o2.getAge()){
            return 1;
        }else if(o1.getAge()<o2.getAge()){
            return -1;
        }else{
            return 0;
        }
    }

    /*测试TreeSet*/
    @org.junit.Test
    public void treeSetTest(){
        TreeSet treeSet = new TreeSet(new Test()); //需要将比较器传递到集合中
        TreeSet treeSet1 = new TreeSet();
        /*常用api*/
        treeSet.add("lisi");
        treeSet.addAll(treeSet1);
        treeSet.ceiling("lisi");
        treeSet.clear();
        treeSet.clone();
        treeSet.comparator();
        treeSet.contains("lisi");
        treeSet.first();
        treeSet.isEmpty();
        treeSet.iterator();
        treeSet.remove("lisi");
        treeSet.size();



    }

    /*HashSet测试*/
    @org.junit.Test
    public void hashSetTest(){
        HashSet hashSet = new HashSet();

        /*常用api*/
        hashSet.add("lisi");
        hashSet.clear();
        hashSet.iterator();
        hashSet.size();
        hashSet.clone();
        hashSet.contains("lisi");
        hashSet.isEmpty();
        hashSet.remove("lisi");
        hashSet.equals(hashSet);
        hashSet.hashCode();
        hashSet.toArray();

    }

    /*测试Set*/
    @org.junit.Test
    public void setTest(){
        Set set = new HashSet();
        set.add("123");
        set.add(1);
        set.add(true);
        set.add("123");//重复数据
        System.out.println(set);  // [1, 123, true] 无序、唯一

        //两种打印set的方式
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //将while改为for循环
        for(Iterator iterator1 = set.iterator();iterator1.hasNext();) {
            System.out.println(iterator1.next());
        }

        set.add("lisi"); //添加
        set.clear();//清除
        set.hashCode();//返回哈希值
        set.size();//取大小
        set.contains("lisi");//判断是否包含指定元素
        set.containsAll(set);
        set.equals(set);
        set.isEmpty();
        set.remove("lisi");
        set.removeAll(set);
        set.retainAll(set);
        set.toArray();
    }

    /*Test Dog*/
    @org.junit.Test
    public void demoTest(){
        List list = new ArrayList();
        //添加狗的信息
        Dog d1 = new Dog("大黄","red");
        Dog d2 = new Dog("二黄","red");
        Dog d3 = new Dog("三黄","red");
        list.add(d1);
        list.add(d2);
        list.add(d3);
        System.out.println(list);
        System.out.println(list.size());
        list.remove(d1);
        System.out.println(list);
        System.out.println(list.contains(d2));
        Dog d4 = new Dog("二黄","red");
        System.out.println(list.contains(d4));

    }

    /*测试Iterator*/
    @org.junit.Test
    public void iteratorTest(){
        ArrayList arrayList = new ArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(6);
        arrayList.add(4);
        arrayList.add(7);
        arrayList.add(9);

        System.out.println("普通for循环");
        for (int i = 0;i<arrayList.size();i++){
            System.out.println(arrayList.get(i));
        }

        //迭代器
        System.out.println("迭代器");
        Iterator iterator = arrayList.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //增强for循环
        System.out.println("增强佛如循环");
        for (Object i:arrayList) {
            System.out.println(i);
        }
    }


    /*测试LinkedList*/
    @org.junit.Test
    public void linkedList(){
        LinkedList linkedList = new LinkedList();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add("dfcd");
        linkedList.add("vd");
        linkedList.add("a");
        linkedList.add("a");
        linkedList.add("vio");
        linkedList.add(10);
        System.out.println(linkedList);

    }

    /*测试List
    *存储对象不唯一,有序(插入数据的顺序)
   */
    @org.junit.Test
    public void listTest(){
        List list = new ArrayList();
        //插入数据
        list.add("a");
        list.add("b");
        list.add(1);
        list.add(3);
        list.add(4);
        list.add("a");
        System.out.println(list);
    }

    /*测试Collection*/
    @org.junit.Test
    public void CollectionTest(){
        Collection collection = new ArrayList();
        collection.add(1);
        collection.add(true);
        collection.add(1.23);
        collection.add("abc");
        System.out.println(collection);

        //在指定位置加入数据
        ((ArrayList)collection).add(0,"lxg");
        System.out.println(collection);

        //在一个集合后面增加另外一个集合
        Collection collection1 = new ArrayList();
        collection1.add("a");
        collection1.add("b");
        collection1.add("c");
        collection1.add("d");
        collection.addAll(collection1);
        System.out.println(collection);

        //清空集合中的元素
        Collection collection2 = new ArrayList();
        collection2.add(1);
        collection2.add(2);
        collection2.clear();
        System.out.println("collection2:"+ collection2);
        System.out.println(collection2);
    }



}

CollectionDemo

package com.lxg.JHDemo;

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

/**
 * @author lxg
 * @description 集合框架类
 * @date 2021/9/4
 */
public class CollectionDemo {
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        collection.add(1);
        collection.add(true);
        collection.add(1.23);
        collection.add("abc");
        System.out.println(collection);

        //在指定位置加入数据
        ((ArrayList)collection).add(0,"lxg");
        System.out.println(collection);

        //在一个集合后面增加另外一个集合
        Collection collection1 = new ArrayList();
        collection1.add("a");
        collection1.add("b");
        collection1.add("c");
        collection1.add("d");
        collection.addAll(collection1);
        System.out.println(collection);
    }
}

Dog类,测试List

package com.lxg.JHDemo;

import java.util.Objects;

/**
 * @author lxg
 * @description Dog类,测试List
 * @date 2021/9/5
 */
public class Dog {
    private String name;
    private String color;

    public Dog(){

    }

    public Dog(String name, String color) {
        this.name = name;
        this.color = color;
    }


    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog dog = (Dog) o;
        return Objects.equals(name, dog.name) &&
                Objects.equals(color, dog.color);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, color);
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}

Person

package com.lxg.JHDemo;

import java.util.Objects;

/**
 * @author lxg
 * @description 演示
 * @date 2021/9/6
 */
public class Person implements Comparable{
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.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;
    }

    /*
    * 重写equals和hashCode方法,
    * 保证插入TreeSet时元素唯一性问题
    * */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    /*重写比较器,完成比较,需要实现Comparable接口,在将person对象插入以树结构为底层的集合工具TreeSet中时,
    * 自动调用此方法对person对象进行排序。
    * 按照名字的长度来进行比较
    * */
    @Override
    public int compareTo(Object o) {
        Person p = (Person) o;
        if(p.name.length()>this.name.length()){
            return -1;
        }else if(p.name.length()<this.name.length()){
            return 1;
        }else{
            return 0;
        }
    }

    /*重写toString方法*/
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

泛型类 Fanxing

package com.lxg.JHDemo;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

/**
 * @author lxg
 * @description 泛型类
 * @date 2021/9/6
 *
 * 在定义类的时候,在类名的后面添加<E、K、V、A、B>等,起到占位的作用,类中的方法的返回值类型和属性都可以使用
 */
public class Fanxing<A> {
    private int id;
    private A a;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    public void show(){
        System.out.println("id:"+id+"A:"+a);
    }

    //泛型作为返回值
    public A get(){
        return a;
    }

    //泛型作为参数
    public void set(A a){
        System.out.println("执行set方法"+a);
    }
}

泛型接口 FanxingInterface

package com.lxg.JHDemo;

public interface FanxingInterface<B> {

    //泛型作为方法返回值
    public B test();

    //泛型作为方法参数
    public void test2(B b);
}

package com.lxg.JHDemo;

/**
 * @author lxg
 * @description 泛型接口的实现类
 * @date 2021/9/6
 *
 *
 */
public class FanxingInterfaceImp implements FanxingInterface<String>{
    @Override
    public String test() {
        return null;
    }

    @Override
    public void test2(String s) {

    }

    /*第一种实现方式*/

}

泛型方法 FanxingMethod

package com.lxg.JHDemo;

/**
 * @author lxg
 * @description 泛型方法
 * @date 2021/9/6
 */
public class FanxingMethod <T>{

    private T t;

    public <Q> void show(Q q){
        System.out.println(t);
        //System.out.println(q);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值