java语法(一)基本概念、数据类型、字符串类、集合

news2024/12/24 13:24:51

文章目录

  • java程序运行流程
    • JDK、JRE、JVM的关系
  • java数据类型
    • 基本数据类型
      • 基本数据类型之间的转换
    • 引用数据类型
      • 数组
        • Java Bean
        • 重写 equals和hashcode
      • 接口
      • 接口与类之间的关系
    • 内置包装类
      • 装箱和拆箱
      • 包装类的应用
      • Object类
        • toString()
        • equals()方法
        • getClass() 方法
        • 接收任意引用类型的对象
      • Integer类
      • Float类
    • 字符串类
      • String类常用API
  • 集合
    • 迭代器iterator
    • Collection
    • List
      • List实现ArrayList
      • List实现LinkedList
        • ListIterator
      • List实现vector
      • List实现Stack
    • Queue
      • Deque
      • ArrayDeque
      • PriorityQueue
    • Set
      • HashSet
      • LinkedHashSet
      • TreeSet
    • 双列集合Map
      • Map的4种遍历方式
      • Map实现HashMap
      • Map实现LinkedHashMap
      • Map实现TreeMap

java程序运行流程

源代码.java -> 经过编译器javac.exe编译为java字节码 源代码.class -> 编译完成的代码可以在 java虚拟机JVM中运行。

JDK、JRE、JVM的关系

  • JDK:(java开发工具箱)包含JAVA编译器工具和JRE。常见的java编辑工具有:

    • javac.exe:将java源码编译为java.class字节码的工具
    • java.exe:Java解释器,启动 JVM(Java虚拟机),将 .class 文件一行一行地解释成机器指令执行。(由 Java 虚拟机对字节码进行解释和执行)
  • JRE(java运行环境):它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。

  • JVM:java虚拟机,它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作,jvm 是 Java 能够跨平台的核心。

所以三者的关系是JDK(java开发工具箱)包含JRE(java运行环境),JRE包含JVM(java虚拟机)

在这里插入图片描述

java数据类型

在这里插入图片描述

基本数据类型

Java中定义了四类/八种基本数据类型

  • 布尔型 boolean:只允许赋值truefalse
  • 字符型 char:java字符采用Unicode编码,每个字符占用两个字节,16位。
  • 整数型---- byte, short, int, long,占用字节数和可表示范围依次翻倍
  • 浮点数型---- float, double
    在这里插入图片描述
    在这里插入图片描述
    整数类型byte、short、int、long占用的空间倍数上升。

默认的小数类型为double,如果要给浮点数类型赋值,需要在小数后边+f或F表示浮点数。
在这里插入图片描述

基本数据类型之间的转换

自动类型转换:表示数据范围从小到大。
在这里插入图片描述
强制类型转换:如果是浮点数类型转为整数会去掉小数部分,丢失精度;
如果是整数类型之间或者浮点数类型之间由高范围转为低范围,会直接丢弃高位部分,导致原本的超出范围的正数可能出现负数
在这里插入图片描述

引用数据类型

引用数据类型建立在基本数据类型的基础上,包括数组、类和接口。

引用类型还有一种特殊的 null 类型。在实际开发中,程序员可以忽略 null 类型,假定 null 只是引用类型的一个特殊直接量。

注意:空引用(null)只能被转换成引用类型,不能转换成基本类型,因此不要把一个 null 值赋给基本数据类型的变量。

数组

长度固定,存放同一种数据类型的连续存储空间。

类是具有相同属性和服务的一组对象的集合。为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务(功能)两个主要部分。

Java Bean

在java编程中,在编写一个具体的类时通常会包含:

  • 一个默认的无参构建器,一个有参构造器
  • 需要被序列化并且实现了序列化接口,一般是重写toString,将属性展示出
  • 可能有一系列的可读写属性,并且一般是private的
  • 有一系列的get、set方法

符合上边条件的类称为一个java bean。

java bean最大的特征是私有的属性,其作用也就是把一组数据组合成一个特殊的类便于传输。 例如:将所需要的物品放到箱子指定的格子当中,然后快递员将打包好的箱子发出去。这个箱子就是 Java Bean。

重写 equals和hashcode

equals()定义在Object类中,其底层是通过 ==来比较,也就是说通过比较两个对象的内存地址是否相同来判断是否是同一个对象。

很多对象都会重写equals这个方法,因为我们实际上想要的结果是比较两个对象的内容是否一致。
例如String类中就重写了equals:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String aString = (String)anObject;
        if (coder() == aString.coder()) {
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                              : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

hashcode是由对象的地址计算得到的哈希码,这个hashcode值决定了对象存放在哈希表中的位置。
常见的散列表实现方式:用数组作为哈希函数的输出域,输入值经过哈希函数计算后得到哈希值。然后根据哈希值,在数组种找到对应的存储单元。当发生冲突时,对应的存储单元以链表的形式保存冲突的数据(链地址法)。

在这里插入图片描述

hashcode可以起到一定的判重作用,即hashcode值不一样,对象一定不一样。但hashcode一样的对象,可能也不相同,因为有哈希冲突!!!

按照重写equals的思路,我们判断两个对象是否一致,是比较他们的内容是否一致,那么根据地址计算的hashcode,也是不符合要求的!!!

因此重写equals()方法,必须同时重写hashcode()方法。
例如在下边这个类中,重写的equals,是在比较类的三个属性size、color、index是否相同,而重写的hashcode,是根据类的三个属性size、color、index计算得到的hashcode。

public class Card {
    private String size;
    private String color;
    private int index;

    public Card(){

    }

    public Card(String size, String color, int index) {
        this.size = size;
        this.color = color;
        this.index = index;
    }

    @Override
    public String toString() {
        return  size +
                ","+ color;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Card card = (Card) o;
        return index == card.index && Objects.equals(size, card.size) && Objects.equals(color, card.color);
    }

    @Override
    public int hashCode() {
        return Objects.hash(size, color, index);
    }
}

接口

接口(Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合(接口里面都是抽象方法),接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法,当然接口中也可以定义不需要实现的常量或者static方法。

接口是为了突破java单继承的局限性而来的。

接口与类之间的关系

  • 类与类

    • 类和类之间是继承关系,而且只允许单根继承,子类继承父类后,可以使用父类除封装之外的所有功能。
    • 子类可以修改父类的原有功能,会发生方法重写。
    • 方法重写需要满足方法头要相同,方法要用@Override标识。
    • 重写改变的是方法体,是把子类的方法体改成新的业务
  • 接口与接口之间

    • 接口也可以继承
    • 子接口可以使用父接口的所有功能。
    • 接口是为了突破java单继承的局限性而来的。
    • 接口里没有构造方法,没有变量只有常量,jdk1.8后可以有default或者static的普通方法。
    • 接口可以多继承,多实现,还可以在继承的同时多实现(先继承再实现)。
  • 类与接口之间

    • 类和接口是实现关系,并且允许多实现
    • 当实现类实现了接口后,需要重写接口里的所有方法,否则就包含 抽象方法,变成了一个抽象类。

内置包装类

在 Java 的设计中提倡一种思想,即一切皆对象。但是从数据类型的划分中,我们知道 Java 中的数据类型分为基本数据类型和引用数据类型,但是基本数据类型怎么能够称为对象呢?于是 Java 为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes)
在这里插入图片描述

装箱和拆箱

基本数据类型转换为包装类的过程称为装箱,例如把 int 包装成 Integer 类的对象;包装类变为基本数据类型的过程称为拆箱,例如把 Integer 类的对象重新简化为 int。

Java 1.5 版本之前必须手动拆箱装箱,之后可以自动拆箱装箱,也就是在进行基本数据类型和对应的包装类转换时,系统将自动进行装箱及拆箱操作,不用在进行手工操作,为开发者提供了更多的方便。例如:

public class Demo {
    public static void main(String[] args) {
        int m = 500;
        Integer obj = m;  // 自动装箱
        int n = obj;  // 自动拆箱
        System.out.println("n = " + n);
      
        Integer obj1 = 500;
        System.out.println("obj等价于obj1返回结果为" + obj.equals(obj1));
    }
}

包装类的应用

1) 实现 int 和 Integer 的相互转换
可以通过 Integer 类的构造方法将 int 装箱,通过 Integer 类的 intValue 方法将 Integer 拆箱。

public class Demo {
    public static void main(String[] args) {
        int m = 500;
        Integer obj = new Integer(m);  // 手动装箱
        int n = obj.intValue();  // 手动拆箱
        System.out.println("n = " + n);
       
        Integer obj1 = new Integer(500);
        System.out.println("obj等价于obj1的返回结果为" + obj.equals(obj1));
    }
}

2) 将字符串转换为数值类型
① Integer 类(String 转 int 型)
int parseInt(String s);
② Float 类(String 转 float 型)
float parseFloat(String s)
注意:使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。

public class Demo {
    public static void main(String[] args) {
        String str1 = "30";
        String str2 = "30.3";
        // 将字符串变为int型
        int x = Integer.parseInt(str1);
        // 将字符串变为float型
        float f = Float.parseFloat(str2);
        System.out.println("x = " + x + ";f = " + f);
    }
}

3) 将整数转换为字符串
Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串。例如:

public class Demo {
    public static void main(String[] args) {
        int m = 500;
        String s = Integer.toString(m);
        System.out.println("s = " + s);
    }
}

Object类

Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类

由于 Java 所有的类都是 Object 类的子类,所以任何 Java 对象都可以调用 Object 类的方法。常见的方法如表 所示。其中,toString()、equals() 方法和 getClass() 方法在 Java 程序中比较常用。
在这里插入图片描述

toString()

Object 类的 toString() 方法返回

“运行时类名@十六进制哈希码”格式的字符串

但很多类都重写了 Object 类的 toString() 方法,用于返回可以表述该对象信息的字符串。

// 定义Demo类,实际上继承Object类
class Demo {
}
public class ObjectDemo01 {
    public static void main(String[] args) {
        Demo d = new Demo(); // 实例化Demo对象
        System.out.println("不加toString()输出:" + d);
        System.out.println("加上toString()输出:" + d.toString());
    }
}

不加toString()输出:Demo@15db9742
加上toString()输出:Demo@15db9742

从程序的运行结果可以清楚的发现,加和不加 toString() 的最终输出结果是一样的,也就是说对象输出时一定会调用 Object 类中的 toString() 方法打印内容

equals()方法

在前面学习字符串比较时,曾经介绍过两种比较方法,分别是==运算符和 equals() 方法.

  • ==运算符是比较两个引用变量是否指向同一个实例
  • equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。

getClass() 方法

getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。

接收任意引用类型的对象

既然 Object 类是所有对象的父类,则所有的对象都可以向 Object 进行转换,在这其中也包含了数组和接口类型,即一切的引用数据类型都可以使用 Object 进行接收。

interface A {
    public String getInfo();
}
class B implements A {
    public String getInfo() {
        return "Hello World!!!";
    }
}
public class ObjectDemo04 {
    public static void main(String[] args) {
        // 为接口实例化
        A a = new B();
        // 对象向上转型
        Object obj = a;
        // 对象向下转型
        A x = (A) obj;
        System.out.println(x.getInfo());
    }
}

通过以上代码可以发现,虽然接口不能继承一个类,但是依然是 Object 类的子类,因为接口本身是引用数据类型,所以可以进行向上转型操作。

Integer类

在这里插入图片描述

Float类

在这里插入图片描述

字符串类

  1. String表示字符串类型,属于 引用数据类型,不属于基本数据类型。
  2. 在java中随便使用 双引号括起来 的都是String对象。
  3. java中规定,双引号括起来的字符串,是 不可变 的,也就是说"abc"自出生到最终死亡,不可变,不能变成"abcd",也不能变成"ab"
  4. 在JDK当中双引号括起来的字符串,例如:“abc” "def"都是直接存储在“方法区”的“字符串常量池”当中的。这是因为字符串在实际的开发中使用太频繁。为了执行效率,所以把字符串放到了方法区的字符串常量池当中。

例子1

public class StringTest01 {
    public static void main(String[] args) {
        // 这两行代码表示底层创建了3个字符串对象,都在字符串常量池当中。
        String s1 = "abcdef";
        String s2 = "abcdef" + "xy";

        // 分析:这是使用new的方式创建的字符串对象。这个代码中的"xy"是从哪里来的?
        // 凡是双引号括起来的都在字符串常量池中有一份。
        // new对象的时候一定在堆内存当中开辟空间。
        String s3 = new String("xy");
    }
}

在这里插入图片描述
例子2

public class StringTest02 {
    public static void main(String[] args) {
        String s1 = "hello";
        // "hello"是存储在方法区的字符串常量池当中
        // 所以这个"hello"不会新建。(因为这个对象已经存在了!)
        String s2 = "hello";
        
        // == 双等号比较的是变量中保存的内存地址
        System.out.println(s1 == s2); // true

        String x = new String("xyz");
        String y = new String("xyz");
        
        // == 双等号比较的是变量中保存的内存地址
        System.out.println(x == y); //false
    }
}

在这里插入图片描述
由此可见:字符串对象之间的比较不能使用“== ”。应该调用String类的equals方法

String类常用API

在这里插入图片描述

集合

集合区分于数组,它的大小是可变的。
数组可以存储基本数据类型和引用数据类型,而集合中只能存储引用数据类型(存储的为对象的内存地址)
单列集合Collection:Queue、List、Set
在这里插入图片描述

双列集合:Map
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

迭代器iterator

迭代器属于设计模式之一,迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而不保留对象的内部表示。iterator仅用于遍历集合,本身不存放对象

所有实现了Collection接口的集合类都有一个iterator(),方法,返回一个实现了iterator接口的对象。

iterator接口包含三个方法:

  • hasNext():迭代器当前位置下一个是否还有元素
  • next():移动迭代器到下一个位置,返回所在位置的元素
  • remove:删除当前迭代器当前位置的元素
    在这里插入图片描述

Collection接口返回的迭代器起初位置集合首元素的前一个位置.
在idea中使用itit快捷输出迭代器遍历方式:

        LinkedList<Integer> L1 = new LinkedList<>();
        Collections.addAll(L1,111,222,333);
        Iterator<Integer> it = L1.iterator();
        while (it.hasNext()) {
            Integer next =  it.next();
            it.remove();
            System.out.println(next);
        }
        System.out.println(L1);

上边代码会依次遍历集合,打印。
它的原理如下图:
1、起初it在集合首元素的前一个位置:
2、调用next,移动迭代器到下一个位置,并返回当前位置的元素。
3、调用迭代器的remove,删除当前位置的元素,使用迭代器删除时会自动更新迭代器和集合(后边的元素前移)
4、当迭代器移动到最后一个位置时,因为没有下一个元素,退出循环。
5、循环外部打印,结果为空列表
在这里插入图片描述

Collection

单列集合的顶层接口,既然是接口就不能直接使用,需要通过实现类!
在这里插入图片描述

List

List表示一串有序的集合,和Collection接口含义不同的是List突出有序的含义。

List其实比Collection多了添加方法add和addAll查找方法get,indexOf,set等方法,并且支持index下标操作。

Collection和List最大的区别就是Collection是无序的,不支持索引操作,而List是有序的,支持索引操作

List实现ArrayList

ArrayList底层就是一个Object[]数组,ArrayList底层数组默认初始化容量为10;

1、jdk1.8 中 ArrayList 底层先创建⼀个⻓度为 0 的数组
2、当第⼀次添加元素(调⽤ add() ⽅法)时,会初始化为⼀个⻓度为 10 的数组

当 ArrayList 中的容量使⽤完之后,则需要对容量进⾏扩容:
1、ArrayList 容ᰁ使⽤完后,会“⾃动”创建容量更⼤的数组,并将原数组中所有元素拷⻉过去,这会导致效率降低。
2、优化:可以使⽤构造⽅法 ArrayList (int capacity) 或 ensureCapacity(int capacity) 提供⼀个初始化容量,避免刚开始就⼀直扩容,造成效率较低。

ArrayList 构造⽅法:

  1. ArrayList():创建⼀个初始化容ᰁ为 10 的空列表
  2. ArrayList(int initialCapacity):创建⼀个指定初始化容ᰁ为 initialCapacity 的空列表
  3. ArrayList(Collection<? extends E> c):创建⼀个包含指定集合中所有元素的列表

ArrayList 特点:

  • 优点:
  1. 向 ArrayList 末尾添加元素(add() ⽅法)时,效率较⾼
  2. 查询效率⾼
  • 缺点:
  1. 扩容会造成效率较低(可以通过指定初始化容量,在⼀定程度上对其进⾏改善)
  2. 另外数组⽆法存储⼤数据量(因为很难找到⼀块很⼤的连续的内存空间)
  3. 向 ArrayList 中间添加元素(add(int index)),需要移动元素,效率较低 ,如果增/删操作较多,可考虑改⽤链表

List实现LinkedList

LinkedList 特点
数据结构: LinkedList 底层是⼀个双向链表
优点: 增/删效率⾼
缺点: 查询效率较低
LinkedList 也有下标,但是内存不⼀定是连续的(类似C++重载[]符号,将循位置访问模拟为循秩访问)
LinkedList 可以调⽤ get(int index) ⽅法,返回链表中第 index 个元素
但是,每次查找都要从头结点开始遍历

ListIterator

ListIterator:列表迭代器,iterator接口的子接口。有如下功能:

  • 允许双向移动迭代器,即可以向前或者向后两个方向遍历List
  • 在遍历时修改List元素的值
  • 遍历时获取迭代器当前位置
  • LinkedList.add()方法只能将数据添加到链表末尾,如果要将对象添加到链表的中间位置,就需要使用 ListIterator

ListIterator的接口定义如下:
在这里插入图片描述

ListIterator 有两种获取方式

  • List.listIterator(),位置在起始位置前一个
  • List.listIterator(int location),位置在索引位置的前一个。

使用ListIterator可以在指定位置插入元素:
因为使用迭代器操作集合(插入或者删除)时,迭代器和集合会更新,所以不会出错。


	private static void listIteratorDemo2(List list) {
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		list.add("abc4");
		
		// 获取列表迭代器
		ListIterator it=list.listIterator();
		
		while(it.hasNext())
		{
			Object obj=it.next();
			if(obj.equals("abc2"))
			{
				it.add("hello");
			}
			System.out.println(obj);
		}
		System.out.println(list);
	}

在这里插入图片描述

List实现vector

vector 是线程安全的,它是操作方法都被synchronize修饰。

vector实际开发使用较少

List实现Stack

Stack也是List接口的实现类之一,和Vector一样,因为性能原因,更主要在开发过程中很少用到栈这种数据结构,不过栈在计算机底层是一种非常重要的数据结构。
栈的最大特点就是后进先出。

Stack<String> strings = new Stack<>();
strings.push("aaa");
strings.push("bbb");
strings.push("ccc");
System.err.println(strings.pop());
复制代码

Queue

Queue是继承自Collection的接口,是一种先进先出的数据结构。

在这里插入图片描述

package java.util;
public interface Queue<E> extends Collection<E> {
     //集合中插入元素
    boolean add(E e);
    //队列中插入元素
    boolean offer(E e);
    //移除元素,当集合为空,抛出异常
    E remove();
    //移除队列头部元素并返回,如果为空,返回null
    E poll();
    //查询集合第一个元素,如果为空,抛出异常
    E element();
    //查询队列中第一个元素,如果为空,返回null
    E peek();
}

Deque

Deque是继承自Queue的接口,相比Queue,支持两端弹出和压入元素。

Deque英文全称是Double ended queue,也就是俗称的双端队列。就是说对于这个队列容器,既可以从头部插入也可以从尾部插入,既可以从头部获取,也可以从尾部获取。

ArrayDeque

ArrayDeque是Java中基于数组实现的双端队列,在Java中Deque的实现有LinkedList和ArrayDeque,正如它两的名字就标志了它们的不同,LinkedList是基于双向链表实现的,而ArrayDeque是基于数组实现的。
在这里插入图片描述
在这里插入图片描述

PriorityQueue

PriorityQueue是Java中唯一一个Queue接口的直接实现,如其名字所示,优先队列,其内部支持按照一定的规则对内部元素进行排序。

Set

如果说List对集合加了有序性的化,那么Set就是对集合加上了唯一性。
Set的特点在于不可存放重复元素,没有索引,不能使用普通的for循环遍历,需要使用迭代器,或者for each遍历。

Set集合的功能基本上与Collection的API是一致的。

HashSet

无序、不重复、无索引

HashSet集合,底层采用哈希表存储数据

  • jdk8之前,底层使用数组+链表组成
  • jdk8之后,底层采用数组+链表+红黑树组成

数组区间作为哈希函数的输出域,当发生哈希冲突时,采用链表的形式,将新的元素挂在数组的下方。当冲突很多时,就可能导致链表过长,导致查询速度变慢,因此jdk8后边的版本中,当链表长度超过8时,会将链表重新组织为红黑树。

在这里插入图片描述

在这里插入图片描述

LinkedHashSet

有序、不重复、无索引
底层数据结构依然是哈希表,只是每个元素额外多了一个双链表机制,记录存储的顺序。

在这里插入图片描述

TreeSet

可排序(自定义比较规则)、不重复、无索引
TreeSet集合是一定要排序的,底层是基于红黑树的数据结构。
在这里插入图片描述
如果要使用TreeSet存放自定义数据类型,一定要自定义比较规则。

自定义比较规则的方式:

  • 方式1:让自定义类(如学生类)实现Comparable接口,重写compareTo方法,来定定制比较规则
  • 方式2:TreeSet集合含有参数构造器,可以设置Comparable接口对应的比较器对象,来定制比较规则。

在这里插入图片描述
即:因为TreeSet要保证唯一性,因此当比较规则返回0的时候,认为元素重复,会将重复元素去除,然而实际应用中,可能比较规则只针对于对象的某一个属性,对象的某一个属性相同,不能认为,对象重复,因此,注意过滤掉返回0的情况。

在这里插入图片描述

双列集合Map

Map是一种键值对的结构,就是常说的Key-Value结构,一个Map就是很多这样K-V键值对组成的,一个K-V结构我们将其称作Entry,在Java里,Map是用的非常多的一种数据结构。
在这里插入图片描述

Map的4种遍历方式

1)在 for 循环中使用 entries 实现 Map 的遍历(最常见和最常用的)。

public static void main(String[] args) {
    Map<String, String> map = new HashMap<String, String>();
    map.put("Java入门教程", "http://c.biancheng.net/java/");
    map.put("C语言入门教程", "http://c.biancheng.net/c/");
    for (Map.Entry<String, String> entry : map.entrySet()) {
        String mapKey = entry.getKey();
        String mapValue = entry.getValue();
        System.out.println(mapKey + ":" + mapValue);
    }
}

2)使用 for-each 循环遍历 key 或者 values,一般适用于只需要 Map 中的 key 或者 value 时使用。性能上比 entrySet 较好。

Map<String, String> map = new HashMap<String, String>();
map.put("Java入门教程", "http://c.biancheng.net/java/");
map.put("C语言入门教程", "http://c.biancheng.net/c/");
// 打印键集合
for (String key : map.keySet()) {
    System.out.println(key);
}
// 打印值集合
for (String value : map.values()) {
    System.out.println(value);
}

3)使用迭代器(Iterator)遍历

Map<String, String> map = new HashMap<String, String>();
map.put("Java入门教程", "http://c.biancheng.net/java/");
map.put("C语言入门教程", "http://c.biancheng.net/c/");
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
    Entry<String, String> entry = entries.next();
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println(key + ":" + value);
}

4)通过键找值遍历,这种方式的效率比较低,因为本身从键取值是耗时的操作,不推荐使用。

for(String key : map.keySet()){
    String value = map.get(key);
    System.out.println(key+":"+value);
}

Map实现HashMap

HashMap是Java中最常用K-V容器,采用了哈希的方式进行实现,HashMap中存储的是一个又一个Key-Value的键值对,我们将其称作Entry,HashMap对Entry进行了扩展(称作Node),使其成为链表或者树的结构使其存储在HashMap的容器里(是一个数组)。

在这里插入图片描述

Map实现LinkedHashMap

在这里插入图片描述

Map实现TreeMap

  1. TreeSet/TreeMap 是⾃平衡⼆叉树
  2. TreeSet/TreeMap 迭代器采⽤的是中序遍历⽅式
  3. ⽆序,不可重复,但是可排序。

排序规则定义与TreeSet类似。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/496278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【蓝桥杯选拔赛真题56】Scratch画笔涂色 少儿编程scratch图形化编程 蓝桥杯选拔赛真题讲解

目录 scratch画笔涂色 一、题目要求 编程实现 二、案例分析 1、角色分析

STM32 匿名助手提升电机控制调试效率(下位机代码和上位机操作演示)

目录 前言 通信协议选择 上位机配置实现 下位机代码实现 通信效果演示 总结 前言 前面介绍了通过VOFA上传变量并显示成波形方便调试的方法&#xff0c;VOFA上传的是浮点&#xff0c;一个浮点需要4个byte才能够表示&#xff0c;这对本就不是很快的串口带来说有不小负担&am…

Django框架之模型自定义管理器

类属性 objects 是manager类的一个对象&#xff0c;作用是与数据库进行交互。 当定义模型类没有指定管理器&#xff0c;django会为模型创建objects管理器。 表结构与数据 CREATE TABLE myapp_grades (id int(11) NOT NULL AUTO_INCREMENT,name varchar(20) NOT NULL,boy_num…

疫情红利出清后如何破局?华大智造的三场突围战

作者&#xff5c;严睿 华大智造&#xff08;688114.SH&#xff09;上市后的首份年报&#xff0c;亮点颇多。 比如2022年公司营收再创新高&#xff0c;达到42.31亿元&#xff0c;净利润同比增长3倍余&#xff1b;比如2022年度华大智造基因测序仪全球装机量达到600&#xff0c;…

处理日期和时间的 chrono 库

C11 中提供了日期和时间相关的库 chrono&#xff0c;通过 chrono 库可以很方便地处理日期和时间&#xff0c;为程序的开发提供了便利。chrono 库主要包含三种类型的类&#xff1a;时间间隔duration、时钟clocks、时间点time point。 1. Ratio 时间精度(节拍) std::chrono::ra…

helm和chart

Helm helm是Kubernetes 应用的包管理工具&#xff0c;主要用来管理 Charts&#xff0c;类似Linux系统的yum。Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata&#xff0c;以便于应用程序的分发。 he…

Linux驱动编程(总线设备驱动模型)

一、驱动编写的3种方法 1、传统写法 使用哪个引脚&#xff0c;怎么操作引脚&#xff0c;都写死在代码中。最简单&#xff0c;不考虑扩展性&#xff0c;可以快速实现功能。修改引脚时&#xff0c;需要重新编译。 2、总线设备驱动模型 引入 platform_device/platform_driver&am…

【.NET基础加强第八课--委托】

.NET基础加强第八课--委托 委托&#xff08;Delegate&#xff09;委托操作顺序实例多播委托—委托链实例实例委托传值 委托&#xff08;Delegate&#xff09; 委托&#xff08;Delegate&#xff09; 是存有对某个方法的引用的一种引用类型变量 委托操作顺序 1,定义一个委托类…

SpringCloud------Eureka修改实例显示信息、服务发现Discovery、自我保护(六)

SpringCloud------Eureka修改实例显示信息、服务发现Discovery、自我保护&#xff08;六&#xff09; 1.actuator微服务信息完善 2.服务发现Discovery 3.Eureka自我保护 actuator微服务信息完善 web和actuator依赖用于图形化监控 1.主机名称&#xff1a;服务名称修改 新增…

新库上线 | CnOpenData缺陷产品召回数据

缺陷产品召回数据 一、数据简介 缺陷产品召回&#xff0c;是指缺陷产品的生产商、销售商、进口商在得知其生产、销售或进口的产品存在可能引发消费者健康、安全问题的缺陷时&#xff0c;依法向职能部门报告&#xff0c;及时通知消费者&#xff0c;设法从市场上、消费者手中收回…

快速跑通环信IM Android Demo

1、以Android 4.0.0 Demo为例 https://www.easemob.com/download/demo &#xff08;下载别的版本的demo 可以修改版本号直接下载就就可以&#xff09; https://downloadsdk.easemob.com/downloads/easemob-sdk-4.0.0.zip 运行时遇到以下报错在项目build.gradle中添加运行时遇…

SAXS测试在材料结构表征中的应用与优势

SAXS测试在材料结构表征中的应用与优势 SAXS是指小角X射线散射&#xff0c;是一种用于研究物质结构的重要技术。SAXS技术可以用于表征各种材料的结构&#xff0c;如聚合物、胶体、纳米粒子等。本文将介绍SAXS测试在材料测试表征中的应用&#xff0c;包括SAXS曲线、比表面积、粒…

MySQL基础(四)运算符

1. 算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&#xff08;%&am…

选对信息化管理系统,企业运营效率大幅提升!

随着信息化的发展&#xff0c;企业信息化管理系统已经成为企业独立商业活动和发展的重要基础设施之一。然而&#xff0c;在众多的信息化管理系统中&#xff0c;选择一款适合企业的信息化管理系统并不是一件易事&#xff0c;本文将从选型的角度&#xff0c;为企业提供一些选对合…

第二章 图像基本运算及变换

文章目录 前言一、图像运算1. 加减乘除2. 位运算 二、翻转与旋转1.翻转2.旋转 三、仿射变换1. 介绍2. 变换的数学表达2.1 平移2.2 缩放2.3 旋转 3. 变换矩阵4. 变换叠加5. 变换矩阵的逆推6.OpenCV实现以及手动实现6.1 手动实现6.2OpenCV实现 7.向量空间----补充 四、透视变换1.…

人脉变现小程序裂变定制开发

人脉变现小程序裂变定制开发可以提供以下服务&#xff1a; 需求分析&#xff1a;了解客户的业务需求和目标&#xff0c;并为其量身定制开发方案&#xff0c;提供专业的建议和意见。 UI/UX设计&#xff1a;根据客户的品牌形象和用户体验要求&#xff0c;设计出符合客户需…

简单实现基于UDP与TCP的回显服务器

目录 前言UDP 版的回显服务器需要用到的 api服务端客户端UDP 版本的字典客户端和字典服务器 TCP 版的回显服务器需要用到的 api服务器客户端对服务器进行改进(使用线程池)TCP 版本的字典客户端和字典服务器 前言 我们写网络程序, 主要编写的是应用层代码. 真正要发送这个数据,…

浅谈联网汽车安全漏洞

​“智能网联汽车存在内生共性问题&#xff0c;即软硬件的漏洞后门&#xff0c;基于此进行的网络攻击可以直接带来勒索、盗窃、大规模车辆恶意操控风险&#xff0c;还有数据泄露等网络安全事件。如果内生的漏洞后门问题不解决&#xff0c;系统自身难保&#xff0c;很难谈系统安…

浙大数据结构第四周之二叉搜索树与平衡二叉搜索树(AVL)

题目详情&#xff1a;04-树4 是否同一棵二叉搜索树 给定一个插入序列就可以唯一确定一棵二叉搜索树。然而&#xff0c;一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树&#xff0c;都得到一样的结果。于是…

【Python系列】一个简单的抽奖小程序

序言 很开心你能在万千博文中打开这一篇&#xff0c;希望能给你带来一定的帮助&#xff01;&#x1f44d;&#x1f3fb; 如果有什么问题&#xff0c;都可以添加下方我的联系方式&#xff0c;联系我噢~&#x1f601; ⭐️⭐️⭐️⭐️⭐️沟通交流&#xff0c;一起成为技术达人&…