Java day14——字符集、泛型、数据结构(栈、列表)、List、集合的框架

字符集

String -> 字符序列 (中文\英文)
JVM -> 1个char = 2个byte Unicode
操作系统 -> windows:GBK->GB2312 Linux:UTF-8 ISO8859-1
UTF-8: 1char = 3byte
gbk: 1char = 2byte

编码、解码

byte[] getBytes(); -> 根据默认字符集来编码
new String(bs); -> 按照默认字符集解码

byte[] getBytes(“charset”) -> 按照指定字符集编码
new String(bs1, “gbk”); -> 按照指定字符集解码

      String str = "你好";
      // 字符 -> 字节 (编码)
      byte[] bs = str.getBytes();
      System.out.println(str);
      // [-28, -67, -96, -27, -91, -67]
      System.out.println(Arrays.toString(bs));
      // [-60, -29, -70, -61]
      byte[] bs1 = str.getBytes("GBK");
      System.out.println(Arrays.toString(bs1));

      // 字节 -> 字符 (解码)
      String s1 = new String(bs);
      System.out.println("s1: " + s1);//s1:你好

      String s2 = new String(bs1, "gbk");
      System.out.println("s2: " + s2);//s2: 你好

解决乱码

在这里插入图片描述

	    // 手动制造乱码
        String str = "你好";
        byte[] bs = str.getBytes();
        String s = new String(bs, "ISO8859-1");
        System.out.println(s); // ä½ å¥½
        // ----------------------
        // 将 s 的乱码解决
        /*byte[] b = s.getBytes("ISO8859-1");
        s = new String(b, "UTF-8");
        System.out.println(s);*/

        // 简化成一句话
        s = new String(s.getBytes("ISO8859-1"), "UTF-8");
        System.out.println(s);

泛型

接口/类<泛型/类型>
将类型作为参数, 编译时有效, 规范程序员的 -> 编译时语法
泛型的本质是, 支持Object类型

使用

定义泛型: 类/接口的定义上就加上
在这个类的方法中, 具体类型就可以使用 E 来代替
泛型的意义: 当类/方法 可以支持任意类型时, 就可以将类型动态传入
不确定类型, 但是又想要具体类型

public class GenericClass<T, L> {
    public void print(T a, L b) {
        System.out.println(a + "," + b);
    }

public class Demo03Generic {
    public static void main(String[] args) {
        GenericClass gc =new GenericClass();//使用时没规定类型,就可以使用任意类型object
        gc.print(1, "hehe");

        GenericClass<Date, String>  gc1 = new GenericClass<>();//规定了类型
        gc1.print(new Date(), "hello");
        GenericClass<Date, Date>  gc2 = new GenericClass<>();
        gc2.print(new Date(), new Date(0));
    }
    //1,hehe
	//Thu Jul 23 20:36:14 CST 2020,hello
	//Thu Jul 23 20:36:14 CST 2020,Thu Jan 01 08:00:00 CST 1970

数据结构

数据结构: 存储数据的方式
数组, 链表, 栈, 队列, 二叉树
数组结构: ArrayList
链表结构(双向链表): LinkedList
队列: Queue
栈: Stack, Deque

  • 线性结构有四种:栈、队列、链表、数组

弹夹
push():压栈
pop():弹栈
Stack: 先进后出, 后进先出

public class Stack<T>{
    private Object[] data; // 定义一个用于存数据的仓库
    private int size; // 表示栈中的元素个数

    public Stack(int cap){ // cap: 表示栈的最大容量
        data = new Object[cap];
    }
    // 压栈
    public void push(T a){
        data[size++] = a;
    }
    // 弹栈 -> 从栈顶开始
    public T pop() {
        T a = (T) data[size-1];
        size --;
        return a; // return data[--size]
    }
    // 获取元素个数
    public int size() {
        return size;
    }

    // 判断栈是否满
    public boolean isFull() {
        return size == data.length;
    }
    // 判断栈是否为空
    public boolean isEmpty() {
        return size == 0;
    }
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(data[i]);
            sb.append(",");
        }
        if (size != 0) {
            // 去掉最后一个逗号
            sb.delete(sb.length() - 1, sb.length());
        }
        sb.append("]");
        return sb.toString();
    }
}

public static void main(String[] args){
        Stack<Integer> stack = new Stack(8);
        while (!stack.isFull()) {
            stack.push(3);
        }
        System.out.println(stack);
        while (!stack.isEmpty()) {
            int a = stack.pop();
            System.out.println(a);
        }
        System.out.println(stack);
    }
    //[3,3,3,3,3,3,3,3]
//3
//3
//3
//3
//3
//3
//3
//3
//[]

链表

结点为单位, 只能从head访问
末尾添加元素, 插入元素, 获得指定位置的元素, 删除指定位置元素
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

// 单向链表
public class SingleLinked<T>{
    // 结点类型
    private class Node {
        private T data; // 用于存储数据
        private Node next; // 用于存下一个结点的地址
        public Node(T data) {
            this.data = data;
        }
    }
    // 最开始初始化链表时, head不存储数据, next是null
    private Node head = new Node(null);
    // 添加新的结点
    public void add(T a){
        // 寻找next=null 的结点
        Node node = head;
        while (node.next != null) {
            node = node.next;
        }
        // node.next == null
        node.next = new Node(a);
    }
    // 得到index-1位置上的元素
    private Node getIndexPreNode(int index) {
        Node node = head;
        // 要找到index-1这个位置的Node
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node;
    }
    // 在index位置上插入元素
    public void insert(int index, T a) {
        Node node = getIndexPreNode(index);
        Node node3 = new Node(a);
        node3.next = node.next;
        node.next = node3;
    }
    // 获得index位置上的元素
    public T get(int index) {
        Node node = getIndexPreNode(index);
        return node.next.data;
    }

    // 删除index位置上的元素
    public void remove(int index) {
        Node node = getIndexPreNode(index);
        node.next = node.next.next;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        Node node = head;
        while (node.next != null) {
            node = node.next;
            sb.append(node.data);
            sb.append(", ");
        }
        sb.append("]");
        return sb.toString();
    }
    
public static void main(String[] args){
        SingleLinked<Integer> linked = new SingleLinked();
        linked.add(3);
        linked.add(5);
        linked.add(2);

        linked.insert(1, 8);

        System.out.println(linked);

        System.out.println(linked.get(3));
        linked.remove(2);
        System.out.println(linked);
//[3, 8, 5, 2, ]
//2
//[3, 8, 2, ]

数组和链表的优劣势比较:

1.数组的物理空间连续, 碎片化空间使用不彻底
链表物理空间不连续, 空间使用彻底
2.链表只能从head开始访问, 访问效率低
数组可以随机访问任意元素, 访问效率高
3.链表插入/移除元素, 只需要操作1~2个元素, 效率高
数组插入/移除元素, 涉及到大量元素的移动, 效率低

List有序列表

  • 允许重复元素
  • 有序号/下标,添加顺序就是访问顺序
  • 比collection多了index下标,可以访问获取某一个元素
  • 有两个实现类:ArrayList和LinkedList
  • List的遍历/迭代: 可以用
    Iterator
    forEach
    for

API

可以使用index下标
void add(int index, E element)
void addAll(int index, Collection<? extends E> c)
E set(int index, E element)
E get(int index)
List.subList(index1,index2)获取子集
int indexOf(Object o)
int lastIndexOf(Object o)

E remove(int index)迭代删除,详见day15

  		List<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("赵敏");
        list.add("张三丰");
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            System.out.println(s);
//            list.remove(s);
            list.remove(i);
            i--;
        }
        System.out.println(list);

集合的框架

1.Collection(I): 
    |- List(I) -> 顺序结构(数组和链表):有序,允许有重复值、null值
         |- ArrayList - 底层数据结构:数组,线程不安全、效率高,查询快、增删慢
         |- LinkedList - 底层数据结构:双向链表,底层实现:节点(node)+下一个节点引用(next,pre),
        	 线程不安全、效率高,查询慢、增删快
         |- Vector - 数组,线程安全、效率低,查询快、增删慢
         
ArrayList和vector区别:1.效率 2.扩容机制:arralist1倍,后面两倍
linklist和arraylist区别:	上面总结

    |- Queue(I) -> 队列结构(普通队列)、先进先出,底层实现:数组/链表
         |- Deque(I) 队列结构(双端队列, 栈)
            实现类 |- LinkedList


    |- Set(I) -> 散列结构、无序,是map的映射,是map的key值、不允许重复
        |- HashSet底层数据结构:哈希表(散列表),存储位置:hashcode计算,判断唯一:equals,允许有null值
      	    实现类  |- LinkedHashSet - 底层数据结构:哈希表,有序且唯一,
        |- SortedSet(I)- TreeSet二叉树 -底层数据结构:红黑树,作用:排序,有序且唯一,如何保证元素唯一:equals、0则为相同
以上三个类区分:排序用treeset,有序集合用LinkedHashSet,HashSet用来存储普通数据,


	List和Set的区别:             有序性
							 唯一性
							 获取元素        



2.Map 底层数据结构:哈希表,底层实现:hash值配合使用的数组和链表
迭代方式:keyset,values,entryset
	HashMap 就是Map的实现、特点同上,无序的,key和value都允许有null值、但key上null只能有一个,
		如何保证key值唯一:hashCode和equals判断,线程不安全、效率高,初始容量:16、
		加载因子(扩容):0.75倍开始扩容为原来的两倍、扩容方法resize()
				实现类:LinkedHashMap:独有特点:有序、按插入顺序排序,key和value都允许有null值
	TreeMap 底层数据结构:红黑树,作用:根据key排序
	HashTable 底层数据结构:哈希表,线程安全、效率低,key和value都不允许有null值,无序
	ConcurrentHashMap 底层实现:sagment数组+HashEntry数组,
		特点:锁分离,线程安全、效率低,作用:解决并发问题、效率比hashtable快一些,无序

	hashMap和hashTable区别:线程安全效率
						可否解决并发(多线程)
						继承自
    hashmap与treemap区别,前面用于增删改,后面用于排序



3.Comparable和Comparator	
4.集合的遍历:
	for循环
	迭代器:next,remove
	foreach			
foreach和迭代器区别:不能作删除
for循环和迭代器区别:有下标用for循环,arraylist;linkedlist用迭代器

5.Collections:java.util包下类
						常用方法:sort()排序
								shuffle()打乱
								copy()复制
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值