首页 > 编程语言 >一些java中记忆的问题

一些java中记忆的问题

时间:2024-07-05 10:26:50浏览次数:20  
标签:java 迭代 ArrayList 元素 链表 记忆 集合 一些 节点

什么是封装

封装是将对象的属性和方法(或称为成员)结合成一个独立的单元,隐藏对象的属性和实现细节,仅对外公开接口(方法)与对象进行交互。

链表数据结构

链表是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含数据和一个或多个指向其他节点的引用(即指针)。与数组不同,链表中的元素在内存中不是连续存储的。链表提供了一种灵活的方式来组织数据,尤其适用于需要频繁插入和删除操作的场景。

链表的类型

  1. 单向链表(Singly Linked List)

    • 每个节点包含数据和一个指向下一个节点的引用。
    • 最后一个节点的引用指向 null,表示链表的结束。
  2. 双向链表(Doubly Linked List)

    • 每个节点包含数据、一个指向下一个节点的引用和一个指向前一个节点的引用。
    • 链表的头节点的前引用和尾节点的后引用指向 null
  3. 循环链表(Circular Linked List)

    • 单向或双向链表的一种变体,其中最后一个节点的引用指向头节点,形成一个环。
  4. 双向循环链表(Doubly Circular Linked List)

    • 双向链表的一种变体,最后一个节点的后引用指向头节点,头节点的前引用指向尾节点。

单向链表的实现示例

以下是一个简单的单向链表的实现:

class Node {
    int data;
    Node next;

    Node(int data) {
        this.data = data;
        this.next = null;
    }
}

class SinglyLinkedList {
    Node head;

    // 添加元素到链表的头部
    public void addFirst(int data) {
        Node newNode = new Node(data);
        newNode.next = head;
        head = newNode;
    }

    // 添加元素到链表的尾部
    public void addLast(int data) {
        Node newNode = new Node(data);
        if (head == null) {
            head = newNode;
            return;
        }
        Node current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = newNode;
    }

    // 打印链表中的所有元素
    public void printList() {
        Node current = head;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }
}

public class Main {
    public static void main(String[] args) {
        SinglyLinkedList list = new SinglyLinkedList();
        list.addFirst(1);
        list.addLast(2);
        list.addLast(3);
        list.printList();  // 输出: 1 2 3
    }
}

链表的优点

  1. 动态大小:链表可以动态调整大小,没有固定的容量限制。
  2. 插入和删除效率高:在已知位置插入或删除元素的时间复杂度为O(1)。
  3. 内存利用率高:链表的内存利用率比数组高,因为不需要预先分配大量连续内存。

链表的缺点

  1. 访问效率低:链表不支持高效的随机访问,访问任意元素的时间复杂度为O(n)。
  2. 额外的内存开销:每个节点除了存储数据外,还需要存储指向下一个节点的引用,增加了内存开销。
  3. 复杂的实现:与数组相比,链表的实现和操作更复杂,需要处理指针的维护。

链表的应用场景

  1. 频繁插入和删除操作:例如实现队列、栈等数据结构。
  2. 需要动态调整大小的场景:例如实现链式散列表(Hash Table)。
  3. 内存利用率要求高的场景:例如大数据处理中的内存管理。

arrylist vector linklist 的区别

ArrayListVectorLinkedList 是 Java 中常用的集合类,它们都有各自的特性和用途。以下是它们之间的主要区别:

1. ArrayList

  • 底层实现:基于动态数组。
  • 线程安全:不是线程安全的,多个线程同时访问时需要手动同步。
  • 性能:由于是动态数组,支持快速随机访问(时间复杂度为 O(1)),但在插入和删除元素时,特别是在数组中间位置,会涉及大量元素的移动,性能较低(时间复杂度为 O(n))。
  • 适用场景:适用于频繁读取和访问元素的场景。

2. Vector

  • 底层实现:基于动态数组。
  • 线程安全:线程安全的,所有方法都被 synchronized 修饰,多个线程可以安全地访问。
  • 性能:由于线程安全的开销,性能比 ArrayList 略低。同样支持快速随机访问,但插入和删除元素时性能较低。
  • 适用场景:适用于多线程环境下,需要频繁读取和访问元素的场景。

3. LinkedList

  • 底层实现:基于双向链表。
  • 线程安全:不是线程安全的,多个线程同时访问时需要手动同步。
  • 性能:不支持高效的随机访问(时间复杂度为 O(n)),但在插入和删除元素时,性能较高(在链表两端操作的时间复杂度为 O(1),在中间插入删除的时间复杂度为 O(n))。
  • 适用场景:适用于频繁插入和删除元素的场景。

具体区别总结

  • 实现方式ArrayListVector 基于动态数组实现,而 LinkedList 基于双向链表实现。
  • 线程安全Vector 是线程安全的,ArrayListLinkedList 不是线程安全的。
  • 性能ArrayListVector 提供了快速的随机访问,但插入和删除性能较低;LinkedList 插入和删除性能较高,但随机访问性能较低。
  • 内存使用ArrayListVector 的内存使用更加紧凑,LinkedList 由于每个节点需要存储指针,内存开销较大。

使用示例

import java.util.ArrayList;
import java.util.Vector;
import java.util.LinkedList;

public class Main {
    public static void main(String[] args) {
        // ArrayList 示例
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("A");
        arrayList.add("B");
        System.out.println("ArrayList: " + arrayList);

        // Vector 示例
        Vector<String> vector = new Vector<>();
        vector.add("A");
        vector.add("B");
        System.out.println("Vector: " + vector);

        // LinkedList 示例
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("A");
        linkedList.add("B");
        System.out.println("LinkedList: " + linkedList);
    }
}

选择哪种集合类,取决于具体的使用场景和需求。

迭代器 简述

迭代器(Iterator)是Java集合框架中的一种对象,用于遍历集合(如ArrayListHashSet等)中的元素。它提供了一种统一的方式来访问集合中的每一个元素,而不需要了解集合的底层实现。以下是迭代器的主要特性和使用方法:

主要特性

  1. 遍历集合:迭代器可以遍历集合中的每一个元素。
  2. 无须了解底层实现:使用迭代器时,不需要知道集合的具体实现方式,只需要按照统一的接口操作。
  3. 单向遍历:迭代器通常只能单向遍历集合,从第一个元素开始,一直到最后一个元素。
  4. 安全删除:通过迭代器,可以在遍历过程中安全地删除元素。

常用方法

迭代器接口 (java.util.Iterator) 提供了以下三个主要方法:

  1. boolean hasNext():如果迭代器中还有元素可以迭代,则返回 true
  2. E next():返回迭代器中的下一个元素。
  3. void remove():从集合中删除迭代器返回的上一个元素(可选操作)。

使用示例

以下是使用迭代器遍历 ArrayList 的一个简单示例:

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

public class Main {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        // 获取迭代器
        Iterator<String> iterator = list.iterator();

        // 使用迭代器遍历集合
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }
    }
}

迭代器的优势

  1. 统一遍历方式:无论集合类型是什么,使用迭代器都可以统一地遍历集合。
  2. 避免并发修改异常:在遍历过程中,如果使用集合自身的修改方法(如addremove),可能会导致 ConcurrentModificationException。使用迭代器的 remove 方法可以安全地删除元素。
  3. 简化代码:迭代器可以简化代码,使得遍历集合的代码更加清晰和简洁。

注意事项

  • 只读迭代器:对于某些集合(如Collections.unmodifiableList返回的集合),迭代器可能是只读的,调用 remove 方法会抛出 UnsupportedOperationException
  • 并发修改:如果在迭代过程中修改了集合(不是通过迭代器),可能会导致 ConcurrentModificationException。要在遍历过程中安全地修改集合,应该使用迭代器的 remove 方法。

jdk1.8新特性

JDK 1.8(也称为Java 8)引入了许多新特性和改进,使其成为Java平台的一个重要版本。以下是一些主要的新特性:

  1. Lambda 表达式

    • Lambda 表达式提供了一种简洁的方式来传递行为,使代码更简洁和灵活。
    • 语法:(参数) -> 表达式 (参数) -> { 代码块 }
    • 例如:(int x, int y) -> x + y 表示一个接收两个整数并返回它们和的函数。
  2. 函数式接口

    • 函数式接口是仅包含一个抽象方法的接口,用于Lambda表达式和方法引用。
    • Java 8 提供了许多内置的函数式接口,如 Function<T, R>, Consumer<T>, Supplier<T>, Predicate<T> 等。
    • 可以用 @FunctionalInterface 注解来标识函数式接口。
  3. 方法引用

    • 方法引用提供了一种简洁的Lambda表达式的替代语法。
    • 语法:Class::methodNameinstance::methodName
    • 例如:String::valueOf 表示 valueOf 静态方法的引用。
  4. 接口默认方法

    • 接口现在可以有默认方法,允许在不破坏现有实现的情况下添加新方法。
    • 使用 default 关键字来定义默认方法。
    • 例如:default void log(String message) { System.out.println(message); }
  5. Stream API

    • Stream API 用于处理集合类(如List、Set)的数据操作。
    • 支持对集合进行声明性的数据处理,如过滤、排序、映射等。
    • 例如:List<String> filteredList = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
  6. Optional 类

    • Optional 类用于防止出现空指针异常。
    • 提供了许多方法来安全地处理可能为空的值。
    • 例如:Optional<String> optional = Optional.ofNullable(value);
  7. 新的日期时间 API

    • 引入了 java.time 包,提供了更好的日期时间处理。
    • 包括 LocalDate, LocalTime, LocalDateTime, ZonedDateTime 等类。
    • 例如:LocalDate date = LocalDate.now();
  8. Nashorn JavaScript 引擎

    • Java 8 引入了 Nashorn,一个新的 JavaScript 引擎,用于替代 Rhino。
    • 允许在 Java 应用中嵌入 JavaScript 代码。
  9. Base64 编码和解码

    • 提供了 java.util.Base64 类用于Base64编码和解码。
    • 例如:String encoded = Base64.getEncoder().encodeToString("hello".getBytes());
  10. 并行数组(Parallel Array)

    • 提供了 Arrays.parallelSort 方法,用于并行排序数组,提高大数据集的处理性能。
  11. 改进的集合 API

    • 添加了一些新的方法,如 forEachremoveIfreplaceAllcomputemerge 等。

标签:java,迭代,ArrayList,元素,链表,记忆,集合,一些,节点
From: https://blog.csdn.net/weixin_59335007/article/details/140201256

相关文章

  • Java程序基础
    类名要求:类名必须以英文字母开头,后接字母,数字和下划线的组合习惯以大写字母开头要注意遵守命名习惯,好的类命名:HelloNoteBookVRPlayer不好的类命名:helloGood123Note_Book_World注意到public是访问修饰符,表示该class是公开的。不写public,也能正确编译,但是这个类......
  • Java_MyBatis框架:MyBatis框架
    MyBatis的执行流程先加载配置文件再通过SqlSessionFactoryBuilder创建SqlSessionFactory对象获取SqlSession生成代理对象执行Excutor匹配执行SQL语句MyBatis的一级缓存和二级缓存一级缓存:也叫SqlSession级缓存,无需手动开启,可直接使用,为每个SqlSession单独分配的缓存空间,......
  • Java_多线程:线程池
    1、线程池优点:降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一......
  • 基于Java+SpringBoot+Vue的学生宿舍管理系统的设计与开发(源码+lw+部署文档+讲解等)
    文章目录前言项目背景介绍技术栈后端框架SpringBoot前端框架Vue数据库MySQL(MyStructuredQueryLanguage)具体实现截图详细视频演示系统测试系统测试目的系统功能测试系统测试结论代码参考数据库参考源码获取前言......
  • 什么是构造函数?Java 中构造函数的重载如何实现?
    构造函数,就像是建筑房屋时的奠基仪式,是Java类中一个特殊的方法,主要用于初始化新创建的对象。每当创建一个类的新实例时,构造函数就会自动调用,负责为这个新对象分配内存,并对其进行必要的设置,确保对象处于可用状态。它有着与类同名的特殊身份,没有返回类型,甚至连void也不需要声明......
  • 阿里云OSS存储--java
    在yml文件配置属性,使用@Value进行注入@ComponentpublicclassAliOSSUtils{//外部属性注入@Value("${aliyun.oss.endpoint}")Stringendpoint;//@Value("${aliyun.oss.accessKeyId}")@Value("${aliyun.oss.accessKeySecret}")......
  • Java----String类
    publicintlength()返回此字符串的长度。publicbooleanequals(Strings)比较两个字符串内容是否相同、区分大小写publicbooleanequalsIgnoreCase(StringanotherString)将此字符串与指定对象进行比较,忽略大小写。publiccharcharAt(intindex)返回指定索引......
  • 当管理和维护 Active Directory 环境时,有一些基础的 PowerShell 命令可以帮助进行常规
    当管理和维护ActiveDirectory环境时,有一些基础的PowerShell命令可以帮助进行常规的检查和管理操作。以下是一些常用的基础检查命令示例:1.获取特定用户信息powershellCopyCode#获取特定用户的基本信息Get-ADUser-Identity"username"这个命令用于获取特定用户的基本......
  • Java 有什么工具可以快速将CSV 存入关系型数据库
    在Java中,有多种工具和库可以快速将CSV文件的数据导入到数据库中。以下是几种常用的方法和工具:1.使用OpenCSV和JDBCOpenCSV是一个非常流行的库,可以轻松读取和写入CSV文件。结合JDBC,可以将CSV文件的数据快速存储到数据库中。示例代码首先,添加OpenCSV库的依赖(假设使用Maven):<dep......
  • 以银行卡取钱的流程为例的状态模式的 java 的 demo
    好的,下面我们将用状态模式来实现一个模拟从银行卡取钱的流程。假设我们有以下几个状态:输入卡输入密码选择操作取款取卡我们通过状态模式来实现这些状态之间的切换。状态接口首先,我们定义一个状态接口ATMState://ATMState.javapublicinterfaceATMState{void......