集合加泛型的常用知识

Collection

/*
 * 集合的由来:
 *      我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。
 *      而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢?
 *      数组和StringBuffer。但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组。
 *      而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。
 *
 * 数组和集合的区别?
 *      A:长度区别
 *          数组的长度固定
 *          集合长度可变
 *      B:内容不同
 *          数组存储的是同一种类型的元素
 *          而集合可以存储不同类型的元素
 *      C:元素的数据类型问题
 *          数组可以存储基本数据类型,也可以存储引用数据类型
 *          集合只能存储引用类型
 *
 * 刚说过集合是存储多个元的,但是呢,存储多个元素我们也是有不同需求的:比如说,我要这多个元素中不能有相同的元素,
 * 再比如说,我要这多个元素按照某种规则排序一下。针对不同的需求,Java就提供了不同的集合类,这样呢,Java就提供了很多个集合类。
 * 这多个集合类的数据结构不同,结构不同不重要的,重要的是你要能够存储东西,并且还要能够使用这些东西,比如说判断,获取等。
 * 既然这样,那么,这多个集合类是有共性的内容的,我们把这些集合类的共性内容不断的向上提取,最终就能形成集合的继承体系结构。
 *
 * 数据结构:数据的存储方式。
 * Collection:是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。(后面会慢慢的讲解)
 *
 * Collection的功能概述:
 * 1:添加功能
 *      boolean add(Object obj):添加一个元素
 *      boolean addAll(Collection c):添加一个集合的元素
 * 2:删除功能
 *      void clear():移除所有元素
 *      boolean remove(Object o):移除一个元素
 *      boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有)
 * 3:判断功能
 *      boolean contains(Object o):判断集合中是否包含指定的元素
 *      boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)
 *      boolean isEmpty():判断集合是否为空
 * 4:获取功能
 *      Iterator<E> iterator()(重点)
 * 5:长度功能
 *      int size():元素的个数
 *      面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢?
 * 6:交集功能
 *      boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
 * 7:把集合转换为数组
 *      Object[] toArray()
 */

迭代器的源码

public interface Inteator {
    boolean hasNext();
    Object next();
}

public interface Iterable {
    Iterator iterator();
}

public interface Collection extends Iterable {
    Iterator iterator();
}

public interface List extends Collection {
    Iterator iterator();
}

public class ArrayList implements List {
    public Iterator iterator() {
        return new Itr();
    }

    private class Itr implements Iterator {
        public boolean hasNext() {}
        public Object next(){}
    }

并发修改异常

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.ListIterator;

/*

* 问题?

* 我有一个集合,如下,请问,我想判断里面有没有”world”这个元素,如果有,我就添加一个”javaee”元素,请写代码实现。

*

* ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

* 产生的原因:

* 迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。

* 其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。

* 如何解决呢?

* A:迭代器迭代元素,迭代器修改元素

* 元素是跟在刚才迭代的元素后面的。

* B:集合遍历元素,集合修改元素(普通for)

* 元素在最后添加的。

*/

public class ListIteratorDemo2 {

public static void main(String[] args) {

// 创建List集合对象

List list = new ArrayList();

// 添加元素

list.add(“hello”);

list.add(“world”);

list.add(“java”);

    // 迭代器遍历
    // Iterator it = list.iterator();
    // while (it.hasNext()) {
    // String s = (String) it.next();
    // if ("world".equals(s)) {
    // list.add("javaee");
    // }
    // }

    // 方式1:迭代器迭代元素,迭代器修改元素
    // 而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
    // ListIterator lit = list.listIterator();
    // while (lit.hasNext()) {
    // String s = (String) lit.next();
    // if ("world".equals(s)) {
    // lit.add("javaee");
    // }
    // }

    // 方式2:集合遍历元素,集合修改元素(普通for)
    for (int x = 0; x < list.size(); x++) {
        String s = (String) list.get(x);
        if ("world".equals(s)) {
            list.add("javaee");
        }
    }
    System.out.println("list:" + list);
}

}

ArrayList去重的两种简单方法

import java.util.ArrayList;
import java.util.Iterator;

/*
 * 第一种  创建新的集合
 * ArrayList去除集合中字符串的重复值(字符串的内容相同)
 *
 * 分析:
 *      A:创建集合对象
 *      B:添加多个字符串元素(包含内容相同的)
 *      C:创建新集合
 *      D:遍历旧集合,获取得到每一个元素
 *      E:拿这个元素到新集合去找,看有没有
 *          有:不搭理它
 *          没有:就添加到新集合
 *      F:遍历新集合
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 添加多个字符串元素(包含内容相同的)
        array.add("hello");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("java");
        array.add("world");

        // 创建新集合
        ArrayList newArray = new ArrayList();

        // 遍历旧集合,获取得到每一个元素
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();

            // 拿这个元素到新集合去找,看有没有
            if (!newArray.contains(s)) {
                newArray.add(s);
            }
        }

        // 遍历新集合
        for (int x = 0; x < newArray.size(); x++) {
            String s = (String) newArray.get(x);
            System.out.println(s);
        }
    }
}
import java.util.ArrayList;
import java.util.Iterator;

/*
 * 第二种  在原有的集合上操作
 * 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)
 * 要求:不能创建新的集合,就在以前的集合上做。
 */
public class ArrayListDemo2 {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 添加多个字符串元素(包含内容相同的)
        array.add("hello");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("java");
        array.add("world");

        // 由选择排序思想引入,我们就可以通过这种思想做这个题目
        // 拿0索引的依次和后面的比较,有就把后的干掉
        // 同理,拿1索引...
        for (int x = 0; x < array.size() - 1; x++) {
            for (int y = x + 1; y < array.size(); y++) {
                if (array.get(x).equals(array.get(y))) {
                    array.remove(y);
                    y--;
                }
            }
        }

        // 遍历集合
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
        }
    }
}

**注意**
    **需求:去除集合中自定义对象的重复值(对象的成员变量值都相同)**
 *
 * 我们按照和字符串一样的操作,发现出问题了。
 *      我们必须思考哪里会出问题?
 *      通过简单的分析,我们知道问题出现在了判断上。
 *      而这个判断功能是集合自己提供的,所以我们如果想很清楚的知道它是如何判断的,就应该去看源码。
 * contains()方法的底层依赖的是equals()方法。
 * 而我们的学生类中没有equals()方法,这个时候,默认使用的是它父亲Object的equals()方法
 * Object()的equals()默认比较的是地址值,所以,它们进去了。因为new的东西,地址值都不同。
 * 按照我们自己的需求,比较成员变量的值,重写equals()即可。
 * 自动生成即可。

自定义栈集合

import java.util.LinkedList;

/**

* 自定义的栈集合

*/

public class MyStack {

private LinkedList link;

public MyStack() {
    link = new LinkedList();
}

public void add(Object obj) {
    link.addFirst(obj);
}

public Object get() {
    // return link.getFirst();
    return link.removeFirst();
}

public boolean isEmpty() {
    return link.isEmpty();
}

}

泛型

(1)泛型概述

    是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。

(2)格式:

    <数据类型>
    注意:该数据类型只能是引用类型。

(3)好处:

    A:把运行时期的问题提前到了编译期间
    B:避免了强制类型转换
    C:优化了程序设计,解决了黄色警告线问题,让程序更安全

(4)泛型的前世今生

    A:泛型的由来
        Object类型作为任意类型的时候,在向下转型的时候,会隐含一个转型问题
    B:泛型类
    C:泛型方法
    D:泛型接口
    E:泛型高级通配符
        ?
        ? extends E
        ? super E

(5)我们在哪里使用呢?

    一般是在集合中使用。

Set集合

(1)Set集合的特点

    无序,唯一

(2)HashSet集合(掌握)

    A:底层数据结构是哈希表(是一个元素为链表的数组)
    B:哈希表底层依赖两个方法:hashCode()和equals()
      执行顺序:
        首先比较哈希值是否相同
            相同:继续执行equals()方法
                返回true:元素重复了,不添加
                返回false:直接把元素添加到集合
            不同:就直接把元素添加到集合
    C:如何保证元素唯一性的呢?
        由hashCode()和equals()保证的
    D:开发的时候,代码非常的简单,自动生成即可。
    E:HashSet存储字符串并遍历
    F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)

(3)TreeSet集合

    A:底层数据结构是红黑树(是一个自平衡的二叉树)
    B:保证元素的排序方式
        a:自然排序(元素具备比较性)
            让元素所属的类实现Comparable接口
        b:比较器排序(集合具备比较性)
            让集合构造方法接收Comparator的实现类对象

Collection集合总结

Collection
    |--List 有序,可重复
        |--ArrayList
            底层数据结构是数组,查询快,增删慢。
            线程不安全,效率高
        |--Vector
            底层数据结构是数组,查询快,增删慢。
            线程安全,效率低
        |--LinkedList
            底层数据结构是链表,查询慢,增删快。
            线程不安全,效率高
    |--Set  无序,唯一
        |--HashSet
            底层数据结构是哈希表。
            如何保证元素唯一性的呢?
                依赖两个方法:hashCode()和equals()
                开发中自动生成这两个方法即可
            |--LinkedHashSet
                底层数据结构是链表和哈希表
                由链表保证元素有序
                由哈希表保证元素唯一
        |--TreeSet
            底层数据结构是红黑树。
            如何保证元素排序的呢?
                自然排序
                比较器排序
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
            // 姓名长度
            int num = s1.getName().length() - s2.getName().length();
            // 姓名内容
            int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
                    : num;
            // 年龄
            int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
            return num3;
        }
    });
            如何保证元素唯一性的呢?
                根据比较的返回值是否是0来决定

常见集合数据结构

ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

Map集合

(1)将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

(2)Map和Collection的区别?

    A:Map 存储的是键值对形式的元素,键唯一,值可以重复。夫妻对
    B:Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。光棍

(3)Map接口功能概述

    A:添加功能
    V put(K key,V value):添加元素。这个其实还有另一个功能?先不告诉你,等会讲
    如果键是第一次存储,就直接存储元素,返回null
    如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

    B:删除功能
    void clear():移除所有的键值对元素
    V remove(Object key):根据键删除键值对元素,并把值返回

    C:判断功能
    boolean containsKey(Object key):判断集合是否包含指定的键
    boolean containsValue(Object value):判断集合是否包含指定的值
    boolean isEmpty():判断集合是否为空

    D:获取功能
    Set<Map.Entry<K,V>> entrySet():???
    V get(Object key):根据键获取值
    Set<K> keySet():获取集合中所有键的集合
    Collection<V> values():获取集合中所有值的集合

    E:长度功能
    int size():返回集合中的键值对的对数

(4)Map集合的遍历

    A:键找值
        a:获取所有键的集合
        b:遍历键的集合,得到每一个键
        c:根据键到集合中去找值

    B:键值对对象找键和值
        a:获取所有的键值对对象的集合
        b:遍历键值对对象的集合,获取每一个键值对对象
        c:根据键值对对象去获取键和值

    代码体现:
        Map<String,String> hm = new HashMap<String,String>();

        hm.put("it002","hello");
        hm.put("it003","world");
        hm.put("it001","java");

        //方式1 键找值
        Set<String> set = hm.keySet();
        for(String key : set) {
            String value = hm.get(key);
            System.out.println(key+"---"+value);
        }

        //方式2 键值对对象找键和值
        Set<Map.Entry<String,String>> set2 = hm.entrySet();
        for(Map.Entry<String,String> me : set2) {
            String key = me.getKey();
            String value = me.getValue();
            System.out.println(key+"---"+value);
        }

(5)HashMap集合的练习

    A:HashMap<String,String>
    B:HashMap<Integer,String>
    C:HashMap<String,Student>
    D:HashMap<Student,String>

(6)TreeMap集合的练习

    A:TreeMap<String,String>
    B:TreeMap<Student,String>

(7)案例

    A:统计一个字符串中每个字符出现的次数
    B:集合的嵌套遍历
        a:HashMap嵌套HashMap
        b:HashMap嵌套ArrayList
        c:ArrayList嵌套HashMap

* Hashtable和HashMap的区别?

* Hashtable:线程安全,效率低。不允许null键和null值

* HashMap:线程不安全,效率高。允许null键和null值

集合总结

1:集合

Collection(单列集合)
    List(有序,可重复)
        ArrayList
            底层数据结构是数组,查询快,增删慢
            线程不安全,效率高
        Vector
            底层数据结构是数组,查询快,增删慢
            线程安全,效率低
        LinkedList
            底层数据结构是链表,查询慢,增删快
            线程不安全,效率高
Set(无序,唯一)
        HashSet
            底层数据结构是哈希表。
            哈希表依赖两个方法:hashCode()和equals()
            执行顺序:
                首先判断hashCode()值是否相同
                    是:继续执行equals(),看其返回值
                        是true:说明元素重复,不添加
                        是false:就直接添加到集合
                    否:就直接添加到集合
            最终:
                自动生成hashCode()和equals()即可

            LinkedHashSet
                底层数据结构由链表和哈希表组成。
                由链表保证元素有序。
                由哈希表保证元素唯一。
        TreeSet
            底层数据结构是红黑树。(是一种自平衡的二叉树)
            如何保证元素唯一性呢?
                根据比较的返回值是否是0来决定
            如何保证元素的排序呢?
                两种方式
                    自然排序(元素具备比较性)
                        让元素所属的类实现Comparable接口
                    比较器排序(集合具备比较性)
                        让集合接收一个Comparator的实现类对象
Map(双列集合)
    A:Map集合的数据结构仅仅针对键有效,与值无关。
    B:存储的是键值对形式的元素,键唯一,值可重复。

    HashMap
        底层数据结构是哈希表。线程不安全,效率高
            哈希表依赖两个方法:hashCode()和equals()
            执行顺序:
                首先判断hashCode()值是否相同
                    是:继续执行equals(),看其返回值
                        是true:说明元素重复,不添加
                        是false:就直接添加到集合
                    否:就直接添加到集合
            最终:
                自动生成hashCode()和equals()即可
        LinkedHashMap
            底层数据结构由链表和哈希表组成。
                由链表保证元素有序。
                由哈希表保证元素唯一。
    Hashtable
        底层数据结构是哈希表。线程安全,效率低
            哈希表依赖两个方法:hashCode()和equals()
            执行顺序:
                首先判断hashCode()值是否相同
                    是:继续执行equals(),看其返回值
                        是true:说明元素重复,不添加
                        是false:就直接添加到集合
                    否:就直接添加到集合
            最终:
                自动生成hashCode()和equals()即可
    TreeMap
        底层数据结构是红黑树。(是一种自平衡的二叉树)
            如何保证元素唯一性呢?
                根据比较的返回值是否是0来决定
            如何保证元素的排序呢?
                两种方式
                    自然排序(元素具备比较性)
                        让元素所属的类实现Comparable接口
                    比较器排序(集合具备比较性)
                        让集合接收一个Comparator的实现类对象

2:到底使用那种集合

看需求。

是否是键值对象形式:
    是:Map
        键是否需要排序:
            是:TreeMap
            否:HashMap
        不知道,就使用HashMap。

    否:Collection
        元素是否唯一:
            是:Set
                元素是否需要排序:
                    是:TreeSet
                    否:HashSet
                不知道,就使用HashSet

            否:List
                要安全吗:
                    是:Vector(其实我们也不用它,后面我们讲解了多线程以后,我在给你回顾用谁)
                    否:ArrayList或者LinkedList
                        增删多:LinkedList
                        查询多:ArrayList
                    不知道,就使用ArrayList
        不知道,就使用ArrayList

3:集合的常见方法及遍历方式

Collection:
    add()
    remove()
    contains()
    iterator()
    size()

    遍历:
        增强for
        迭代器

    |--List
        get()

        遍历:
            普通for
    |--Set

Map:
    put()
    remove()
    containskey(),containsValue()
    keySet()
    get()
    value()
    entrySet()
    size()

    遍历:
        根据键找值
        根据键值对对象分别找键和值
时间: 2024-11-10 14:41:03

集合加泛型的常用知识的相关文章

.NET基础 (09)常用集合和泛型

常用集合和泛型1 int[]是引用类型还是值类型2 数组之间如何进行转换3 解释泛型的基本原理4 什么是泛型的主要约束和次要约束 常用集合和泛型1 int[]是引用类型还是值类型 数组类型是一族类型,它们都继承自System.Array,而System.Array又继承自System.Object.所有数组的类型都是引用类型. 引用类型的数组和值类型的数组的内存分配: 2 数组之间如何进行转换 数组类型在符合条件的情况下可以进行隐式地转换,条件包括:数组维数必须相同:目标项目类型和源项目类型必须

HTML5常用知识

今日做项目,涉及到native和H5页面的交互 1.document.readyState document.readyState:判断文档是否加载完成.firefox不支持. 这个属性是只读的,传回值有以下的可能: 0-UNINITIALIZED:XML 对象被产生,但没有任何文件被加载. 1-LOADING:加载程序进行中,但文件尚未开始解析. 2-LOADED:部分的文件已经加载且进行解析,但对象模型尚未生效. 3-INTERACTIVE:仅对已加载的部分文件有效,在此情况下,对象模型是有

集合与泛型

集合类负责存储一系列的个体,其集合的长度可能是不变的或者可变的.相比于普通的数组结构,集合类的功能更加具体. 集合类分为普通(非泛型)集合和泛型集合.泛型集合类的命名空间为集合的一个子命名空间:System.Collections.Generic.非泛型的集合中,所有的成员都被当作为object类型,不同的成员可以拥有不同的数据类型.而泛型的集合所有的成员类型都是相同的. 非泛型集合 所有非泛型集合都实现接口ICollection. 所有非泛型集合中的成员都是object. 集合类的基础接口IC

普通集合和泛型集合的区别,哈希表和字典表的区别,队列和堆栈的区别以及堆和栈的区别。

普通集合和泛型集合的区别: 泛型集合与传统集合相比 类型更安全. 泛型集合无需装箱拆箱操作. 泛型的重要性. 泛型是未来五年的主流技术 ... 通常情况下,建议您使用泛型集合,因为这样可以获得类型安全的直接优点而不需要从基集合类型派生并实现类型特定的成员.此外,如果集合元素为值类型,泛型集合类型的性能通常优于对应的非泛型集合类型(并优于从非泛型基集合类型派生的类型),因为使用泛型时不必对元素进行装箱. 下面的泛型类型对应于现有的集合类型: List 是对应于 ArrayList 的泛型类. Di

C#_集合和泛型

集合 在实际编程中,常会按一定要求来处理和计算一组一组的数据,如堆栈操作.队列操作或系列数据的增.删.改.查.C#提供了数组类型来进行管理,但是这样有个缺点就是数组的大小是固定的.我们可以通过集合类来进行管理.数据集合类都位于System.Collections命名空间中,使用时需引用. 数组和集合的对比: 1.ArrayList类 ArrayList是一个可动态扩充容量的集合. ArrayList 数组集合名 = new ArrayList(); 2.Hashtable类 哈希表Hashtab

加解密入门基础知识

很多人都想学习解密,这东西刚入门时会让人沉迷进去,可以饭不吃.觉不睡.出现这种现像,也许是解密满足了人们的猎奇心里吧.但掌握这方面技术,对自身的 提高确实有好处.可以通过跟踪软件,提高自己的调试技能,并且能了解他人程序思路,使自己写出更好的程序.研究解密技术有助于掌握一些系统底层知识,系统 底层知识绝对是构造起大型软件的坚实基础.许多程序发展,都经历了这一锻炼过程的. 而大多数人可能认为解密是一门高深的学问.造成这种原因是以前这方面 的技术资料缺乏,从而将“解密”这一技能“神”化了.初学者一般不

Python数据分析与挖掘所需的Pandas常用知识

Python数据分析与挖掘所需的Pandas常用知识 前言Pandas基于两种数据类型:series与dataframe.一个series是一个一维的数据类型,其中每一个元素都有一个标签.series类似于Numpy中元素带标签的数组.其中,标签可以是数字或者字符串.一个dataframe是一个二维的表结构.Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签.你可以把它想象成一个series的字典项. Pandas常用知识 一.读取csv文件为dataf

全体快三源码开发Python数据分析与挖掘所需的Pandas常用知识

前言 全体快三源码开发 (http://www.1159880099.com) QQ1159880099 Pandas基于两种数据类型:series与dataframe. 一个series是一个一维的数据类型,其中每一个元素都有一个标签.series类似于Numpy中元素带标签的数组.其中,标签可以是数字或者字符串. 一个dataframe是一个二维的表结构.Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签.你可以把它想象成一个series的字典项.

打造自己的Android常用知识体系

前言 Android常用知识体系是什么鬼?所谓常用知识体系,就是指对项目中重复使用率较高的功能点进行梳理.注意哦,不是Android知识体系. 古语道:学而不思则罔,思而不学则殆.如果将做项目类比为“学”,那么整理就可以类比为“思”. 在做项目过程中总是会遇到使用相同的功能,比如toast.对话框.刷新加载列表.网络框架.数据库等等,一个简单的方法就是从之前的项目中复制粘贴到新项目中,然后做一些个性化修改,好了,这就“大功告成”了.当另外一个新项目用到了,再次复制粘贴.这样是不是很low.但是当