java基础学习总结(九):集合

对象数组

之前我们创建数组存储基本数据类型常量数据,比如创建一个数组来存储整数:int[] arr = new int[3];我们要存储String类型的数据,则需要创建String类型的数组:String[] arr=new String[3];我们可以按照定义String类型的数组去定义自定义类型的数组。比如:Student类

public class ArrayDemo {
	public static void main(String[] args) {
		//创建Student类型的数组
		Student[] arr=new Student[3];
		//创建Student类的对象
		Student s1=new Student("heixuanfeng",19);
		Student s2=new Student("bandao",18);
		Student s3=new Student("zhujiao",20);
		//将学生对象存储到数组中
		arr[0]=s1;
		arr[1]=s2;
		arr[2]=s3;
		//遍历数组
		for (int i = 0; i < arr.length; i++) {
			//通过数组名和下标取出Student类的数组中的数据 arr[i]
			Student s=arr[i];
			//输出数据
			System.out.println(s.getName()+"====="+s.getAge());
		}
	}
}

对象数组的内存图
在这里插入图片描述
我们发现上面这样操作比较麻烦,有没有更加简单的,之前学习了三种存储数据的容器:变量 、数组、字符串缓冲区。这里我们学习集合容器。

集合

集合就是一个容器. 是一个长度可变的容器, 底层就是可变数组,可以存放数据。

1、集合与数组区别

  • 从长度来讲:
    数组:需要固定长度。
    集合:长度可以改变,可以根据保存的数据进行扩容。
  • 从存储内容上:
    数组:可以存储基本类型数据,还可以存储引用类型的数据(比如:String和上述演示的Student类)。
    集合:只能存储引用类型的数据,也就是说集合只能存储类的对象。
  • 从存储类型上:
    数组:只能存储相同类型的数据。
    集合:可以存储不同类型的数据,集合中可以存储任意类型的引用数据类型。

集合图解:
在这里插入图片描述
解释:

  • List , Set, Map都是接口,前两个继承至collection接口,Map为独立接口
  • Set下有HashSet,LinkedHashSet,TreeSet
  • List下有ArrayList,Vector,LinkedList
  • Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
  • collection接口下还有个Queue接口,有PriorityQueue类

注意:
1、Queue接口与List、Set同一级别,都是继承了collection接口。LinkedList既可以实现Queue接口,也可以实现List接口。LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。
2、SortedSet是个接口,它里面的(只有TreeSet这一个实现可用)元素一定是有序的。

Collection接口

  • List子接口:有序,可重复
    ArrayList
    优点: 底层数据结构是数组,查询快,增删慢。
    缺点: 线程不安全,效率高
    Vector
    优点: 底层数据结构是数组,查询快,增删慢。
    缺点: 线程安全,效率低
    LinkedList
    优点: 底层数据结构是链表,查询慢,增删快。
    缺点: 线程不安全,效率高
  • Set子接口:无序,唯一
    HashSet
    底层数据结构是哈希表。(无序,不可重复)
    如何来保证元素唯一性?依赖两个方法:hashCode()和equals()
    LinkedHashSet
    底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
    1.由链表保证元素有序
    2.由哈希表保证元素唯一
    TreeSet
    底层数据结构是红黑树。(唯一,有序)
    1.如何保证元素排序的呢? (自然排序,比较器排序)
    2.如何保证元素唯一性的呢? (根据比较的返回值是否是0来决定)

TreeMap

TreeMap底层是红黑树结构,作为Map的一员,包含着key–value形式的元素,和HashMap最大的区别是丢进去的东西自动排序。要注意的是默认的是对Key排序,也可以重写Comparator对Value排序,很方便。

// TreeMap继承关系
public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{}

public abstract class AbstractMap<K,V> implements Map<K,V> {}

构造器

(1) 使用无参构造器创建对象,默认会调用Comparable的compareTo方法排序(自然排序)

TreeMap<String, Object> treeMap = new TreeMap<>();
treeMap.put("id", 1);
treeMap.put("name", "tom");
treeMap.put("age", 13);
// {age=13, id=1, name=tom}
System.out.println(treeMap);

// 无参构造器
public TreeMap() {
    comparator = null;
}

(2) 使用有参构造器创建对象,且这个参数是Comparator类型参数,可以指定key的比较方式

// 这里指定按了按照key的长度来排序
TreeMap<String, Object> comparatorTreeMap = new TreeMap<>(Comparator.comparingInt(String::length));
comparatorTreeMap.put("id", 1);
comparatorTreeMap.put("name", "tom");
comparatorTreeMap.put("age", 13);
comparatorTreeMap.put("z", 13);
// {z=13, id=1, age=13, name=tom}
System.out.println(comparatorTreeMap);

// 带Comparator参数的构造器
public TreeMap(Comparator<? super K> comparator) {
    this.comparator = comparator;
}

(3) 构造器可以接收一个map实现类的参数,如果这个map实现类是SortedMap接口实现类,则按照SortedMap中的排序规则进行排序;如果是其它的map,则按照TreeMap默认的排序

HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("id", 1);
hashMap.put("name", "tom");
hashMap.put("age", 13);
TreeMap<String, Object> map = new TreeMap<>(hashMap);
// {age=13, id=1, name=tom}
System.out.println(map);

// 有参构造,参数是Map类型
public TreeMap(Map<? extends K, ? extends V> m) {
    comparator = null;
    putAll(m);
}
// putAll 方法的实现
public void putAll(Map<? extends K, ? extends V> map) {
    int mapSize = map.size();
    // 如果map是SortedMap类型
    if (size==0 && mapSize!=0 && map instanceof SortedMap) {
    	// 将SortedMap类型实现类的comparator赋值给c
        Comparator<?> c = ((SortedMap<?,?>)map).comparator();
        // 如果传入map的比较器和TreeMap的一致,则按照
        if (c == comparator || (c != null && c.equals(comparator))) {
            ++modCount;
            try {
                buildFromSorted(mapSize, map.entrySet().iterator(),
                                null, null);
            } catch (java.io.IOException cannotHappen) {
            } catch (ClassNotFoundException cannotHappen) {
            }
            return;
        }
    }
    super.putAll(map);
}

(4) 构造器可以接收一个SortedMap类型的参数,按照sortedMap指定的排序规则进行排序

TreeMap<String, Object> param = new TreeMap<>(Comparator.comparingInt(String::length));
param.put("id", 1);
param.put("name", "tom");
param.put("age", 13);
param.put("z", 13);
TreeMap<String, Object> treMap = new TreeMap<>(param);
System.out.println(treMap);

// 有参构造,接收一个SortedMap类型参数
public TreeMap(SortedMap<K, ? extends V> m) {
    comparator = m.comparator();
    try {
        buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
    } catch (java.io.IOException cannotHappen) {
    } catch (ClassNotFoundException cannotHappen) {
    }
}

常用方法

TreeMap<String, Object> treeMap = new TreeMap<>();
// 新增数据,如果key判断之后返回0,则会替换掉value
treeMap.put("name", "lucy");
treeMap.put("age", 18);
// key 不允许null 会报空指针异常
treeMap.put(null, 18);
// 获取entrySet进行遍历
Set<Map.Entry<String, Object>> entries = treeMap.entrySet();
for (Map.Entry<String, Object> entry : entries) {
    // name - lucy
    System.out.println(entry.getKey() + " - " + entry.getValue());
}
// forEach进行遍历 name - lucy
treeMap.forEach((x, y) -> System.out.println(x + " - " + y));
// 获取keySet进行遍历
Set<String> keys = treeMap.keySet();
for (String key : keys) {
    // name - lucy
    System.out.println(key + " - " + treeMap.get(key));
}
// 返回与该键至少大于或等于给定键的Entry,如果不存在这样的键的键值映射,则返回null相关联
Map.Entry<String, Object> entry = treeMap.ceilingEntry("name");
if (!Objects.isNull(entry)){
    System.out.println(entry.getValue());
}

treeMap.remove("name");
treeMap.replace("age", 19);
treeMap.clear();

put方法源码

public V put(K key, V value) {
    Entry<K,V> t = root;
    // 如果root是null,说明容器中没元素
    if (t == null) {
    	// key进行类型检查,如果比较器是null,则自然排序,否则指定排序
        compare(key, key); // type (and possibly null) check
		// 创建Entry对象封装数据
        root = new Entry<>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    int cmp;
    Entry<K,V> parent;
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    // 比较器不为null
    if (cpr != null) {
        do {
            parent = t;
            // 使用比较器进行比较
            cmp = cpr.compare(key, t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
            	// 如果比较返回0说明是相等,替换旧值
                return t.setValue(value);
        } while (t != null);
    }
    else {
    	// key 不能为null
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
        	// 自然排序
            Comparable<? super K> k = (Comparable<? super K>) key;
        do {
            parent = t;
            cmp = k.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    // 封装数据
    Entry<K,V> e = new Entry<>(key, value, parent);
    if (cmp < 0)
        parent.left = e;
    else
        parent.right = e;
    fixAfterInsertion(e);
    size++;
    modCount++;
    return null;
}

Entry 是TreeMap的静态内部类

static final class Entry<K,V> implements Map.Entry<K,V> {
    K key;
    V value;
    Entry<K,V> left;
    Entry<K,V> right;
    Entry<K,V> parent;
    boolean color = BLACK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java基础学习笔记 # 一、Java简介 Java是一种面向对象的编程语言,由Sun Microsystems(现在是Oracle)于1995年首次发布。它具有跨平台的特性,可以在不同的操作系统上运行。Java语言被广泛应用于开发各种类型的应用程序,包括桌面应用、Web应用、移动应用等。 # 二、Java基本语法 ## 1. 变量与数据类型 Java是强类型语言,每个变量必须先声明后使用。Java提供了多种数据类型,包括基本数据类型(整数、浮点数、字符、布尔值)和引用数据类型(类、接口、数组)。 ## 2. 运算符 Java提供了多种运算符,包括算术运算符、关系运算符、逻辑运算符等,用于进行各种数学或逻辑运算。 ## 3. 控制流程 Java提供了多种控制流程语句,包括条件语句(if-else语句、switch语句)、循环语句(for循环、while循环)、跳转语句(break语句、continue语句)等,用于控制程序的执行流程。 ## 4. 方法和类 Java中的方法用于封装一段可重复使用的代码,可以带有参数和返回值。类是Java程序的基本组织单位,包含了属性和方法。可以使用关键字class定义一个类,通过实例化类的对象来调用其方法。 # 三、面向对象编程 Java是一种面向对象的编程语言,面向对象编程的核心概念包括封装、继承和多态。 ## 1. 封装 封装是将数据和行为打包成一个类,通过访问修饰符(public、private等)控制对类的成员的访问权限。 ## 2. 继承 继承允许一个类继承另一个类的属性和方法,并且可以通过重写来修改或扩展继承的方法。 ## 3. 多态 多态允许通过父类类型的引用来引用子类对象,实现对不同子类对象的统一调用。 # 四、异常处理 Java提供了异常处理机制,用于处理程序中的错误情况。异常分为可检查异常(checked exception)和不可检查异常(unchecked exception),可以使用try-catch语句来捕获和处理异常。 # 五、Java标准库 Java标准库提供了大量的类和接口,用于完成各种常见的任务。其中包括输入输出、集合、多线程、网络编程等功能,可以大大简化开发过程。 以上是我学习Java基础的笔记总结,希望对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值