[黑马程序员]--集合基础知识小结与泛型

------- android培训java培训、期待与您交流! ----------

1,基础知识

|--1,数组的优缺点

数组长度不可变
数组不能添加删除元素
数组没有操作方法(查看数组中某个元素是否存在等方法)
数组中的元素在内存中是邻居,索引速度天下无敌!

|--2.1 常见的数据结构

1 常见数据结构有哪些
 栈、队列、数组、链表


2 栈(Last In First Out)
后进先出,最上面的元素我们叫栈顶元素!
出栈(弹栈),就是把栈顶元素从栈中移除,并返回。
压栈,就是把一个新元素放到栈顶位置。


3 队列(FIFO)
先进先出!
没底的管道!


4 数组
数组索引元素的速度天下无敌!
arr[10] – 快速最快!
如果我们需要向数组插入和删除元素,那么就需要copy数组。


5 链表
链表元素在内存中不是邻居,链表头元素知道下一个元素的地址,下一个元素又知道下下元素的地址,最后一个元素,即链表尾,它的下一个元素是null。
链表的索引速度很慢,但插入和删除元素快速很快。

|--2.2 哈希表结构


1 桶数组
哈希表是一个桶数组,也就是说一个哈希表中有多个桶!
每个桶可以存放多个元素。可以把桶理解为链表(集合)!这样整个哈希表就是拥有多个链表的集合了。


2 计算桶位
  哈希表中有很多桶,即一个桶数组。所谓桶位就是对应桶数组的下标!


3 添加元素的流程
当把元素添加到哈希表中时,需要先找到元素对应的桶位,然后判断这个桶中是否存在这个元素,如果元素在桶中已经存在,那么添加失败;否则添加成功!
获取元素的哈希码值(使用元素的hashCode()方法);
通过哈希码值计算桶位(可以把哈希码值理解为就是桶位);
遍历桶中元素,使用元素的equals()方法,验证元素是否在桶中已经存在;
存在则添加失败,否则把元素添加到桶中。


4 添加元素的问题
HashSet<Person> set = new HashSet<Person>();
Person p1 = new Person(“zhangSan”, 23, “male”);
Person p2 = new Person(“zhangSan”, 23, “male”);
set.add(p1);
set.add(p2);


上面代码中set.add(p2)的结果会添加成功!也就是说HashSet会认识p1和p2是两个不同对象。如果想让上面代码中set.add(p2)添加失败,我们需要让HashSet认为p1和p2是相等的。
set.add(p2):调用p2的hashCode()方法获取哈希码,通过哈希码找到桶。如果p1与p2的hashCode()不同,那么p2找到的桶就与p1找到的桶不同。
循环遍历p2对应桶中所有元素,使用equals()比较,如果没有相同元素,那么添加p2到这个桶中。
结论:就算p1.equals(p2)结果为true,但p1.hashCode() != p2.hashCode(),那么也是枉然!


5 HashSet保证元素唯一性
  如果两个对象的hashCode()相等,并且使用equals()方法比较返回true,那么这两个对象是相等的。


|--2.3 二叉树


1 什么是二叉树
二叉树也是一种树状结构。
二叉树中每个节点最多有两个子节点。
二叉树中每个节点都比自己左边节点的值大,比右边节点的值小。


2 添加元素
添加进来的第一个元素就是根节点;
然后再添加第二个元素时,与根节点进行比较,如果比根节点大,那么放到根节点的右侧子节点位置;如果比根节点小,那么放到根节点左侧子节点位置;如果与根节点相等,那么添加失败。
添加第三个元素时,先与根比较:
如果比根小,那么再与根的左侧子节点进行比较:
大于左侧节点,新元素放到左节点的右节点位置;
小于左节点,放到左节点的左节点位置;
等于左节点,那么添加失败。
如果比根大,那么再与根的右侧子节点进行比较:
大于右侧节点,新元素放到右节点的右节点位置;
小于左节点,放到左节点的左节点位置;
等于左节点,那么添加失败。
如果等于根节点,那么添加失败。


2. 泛型

|--1. 继承泛型的方法

    |---1.1 继承泛型类

程序如下:

/*
 * 类型参数的名称,都是一个字母。 一般程序员都用T,表示type。 而在Java集合类中用E,表示element
 * 
 * 持有对象 1创建A类对象时需要给T赋值 2继承A类时需要给T赋值 3其实都可以不赋值,那么就相当于赋值为Object
 */
class A<T> {
  T field;

  public A(T t) {
    field = t;
  }

  public T get() {
    return field;
  }
}

// B不是泛型类,所以没有类型变量,那么你也只能给A赋值为常量
class B extends A<String> {
  public B() {
    super("hello");
  }
}

// C是一个泛型类,C可以有两种选择,可以使用本类的类型变量来给A赋值
// 也可以用一个常量来赋值!
class C<T> extends A<T> {
  public C(T t) {
    super(t);
  }
}

    |---1.2 继承泛型方法

程序如下:

interface D<T> {
  public T fun1();

  public void fun2(T t1, T t2);
}

class E implements D<String> {
  @Override
  public String fun1() {
    return null;
  }

  @Override
  public void fun2(String t1, String t2) {
  }
}
 

|---2. 泛型方法

程序如下:

public class FanXing {
  public static void main(String[] args) {
    MyClass.fun("Hello World");
  }
}

class MyClass{
  public static <T> void fun(T t){
    // <T>写在返回值之前
    System.out.println(t);
  } 
}


|---3. 泛型边界

程序如下:

import java.math.BigInteger;

public class Demo3 {
  public static void main(String[] args) {
 AA aa3 = new AA();
 aa3.set(100);
    int i = (Integer)aa3.get();
 System.out.println(i);
 }
}

// 边界可可以是多个,那么就是说类型参数需要是符合两个类型,也就是说,必须其中至少有一个是接口类型。
class AA<T extends Number & java.io.Serializable> {
// 这样定义保证了泛型在一定的范围内使用
// 比如继承了Number就可以在该类中使用Number的方法了
 T t;
  public void set(T t) {
    this.t = t;
 }
  
  public T get() {
    return t;
 }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值