百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Java路径-31-Java数据结构

bigegpt 2025-03-02 16:15 7 浏览

1 枚举(Enumeration)

1.1 Enumeration

源码:

public interface Enumeration {  
   boolean hasMoreElements();  
   E nextElement();  
}

Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素。

这种传统接口已被迭代器取代,虽然Enumeration 还未被遗弃,但在现代代码中已经被很少使用了。尽管如此,它还是使用在诸如Vector和Properties这些传统类所定义的方法中

实例1 :

import java.util.Vector;  
import java.util.Enumeration;  
  
public class EnumerationTester {  
  public static void main(String args[]) {  
     Enumeration days;  
     Vector dayNames = new Vector();  
     dayNames.add("Sunday");  
     dayNames.add("Monday");  
     dayNames.add("Tuesday");  
     dayNames.add("Wednesday");  
     dayNames.add("Thursday");  
     dayNames.add("Friday");  
     dayNames.add("Saturday");  
     days = dayNames.elements();  
     while (days.hasMoreElements()){  
        System.out.println(days.nextElement());  
    }  
  }  
}

运行结果:

Sunday  
Monday  
Tuesday  
Wednesday  
Thursday  
Friday  
Saturday

1.2 枚举类

Java中的枚举其实是一种语法糖,在 JDK 1.5之后出现,用来表示固定且有限个的对象。比如一个季节类有春、夏、秋、冬四个对象;一个星期有星期一到星期日七个对象。这些明显都是固定的,且有限个。

枚举类和普通类的区别

  • 使用 enum 定义的枚举类默认继承 java.lang.Enum 类,即枚举类是不能再继承别的类了。而普通类的一般父类默认是 Object
  • 枚举类的构造器只能使用 private 定义,而普通类的还可以用 public 修饰
  • 枚举类的所有实例必须在枚举类中显示列出(,分隔 ;结尾),列出的实例系统会默认自动添加 public static final 修饰
  • 所有的枚举类都提供了一个 values() 方法,可以用来遍历枚举值

实例:

package cn.fage.enums;  
  
/**  
* @author lin  
* @version 1.0  
* @date 2020-06-19 17:11  
* @Description TODO  
*/  
public enum SeasonTwoArgs {  
  
   /**  
    * 春天  
    */  
   SPRING(1, "春天"),  
   SUMMER(2, "夏天"),  
   AUTUMN(3, "秋天"),  
   WINTER(4, "冬天");  
  
   int key;  
   String msg;  
  
   SeasonTwoArgs(int key, String season) {  
       this.key = key;  
       this.msg = season;  
       System.out.println("初始化:" + this.name() + "," + this.msg + "," + season);  
  }  
  
   // 很多情况,我们可能从前端拿到的值是枚举类的 key ,然后就可以通过以下静态方法获取到对应枚举值  
   public static SeasonTwoArgs valueofKey(Integer key) {  
       for (SeasonTwoArgs season : SeasonTwoArgs.values()) {  
           if (season.key == key) {  
               return season;  
          }  
      }  
       throw new IllegalArgumentException("No element matches " + key);  
  }  
  
  
   public String getMsg() {  
       return msg;  
  }  
  
   public int getKey() {  
       return key;  
  }  
  
   public void setKey(int key) {  
       this.key = key;  
  }  
  
   public void setMsg(String msg) {  
  
       this.msg = msg;  
  }  
  
   public static void main(String[] args) {  
       SeasonTwoArgs autumn = SeasonTwoArgs.AUTUMN;  
       System.out.println("autumn.getKey() = " + autumn.getKey());  
       System.out.println("autumn.getMsg() = " + autumn.getMsg());  
       System.out.println("autumn = " + autumn);  
  
  }  
}

运行结果:

初始化:SPRING,春天,春天  
初始化:SUMMER,夏天,夏天  
初始化:AUTUMN,秋天,秋天  
初始化:WINTER,冬天,冬天  
autumn.getKey() = 3  
autumn.getMsg() = 秋天  
autumn = AUTUMN

枚举类是最完美的单例模式

2 位集合(BitSet)

一个Bitset类创建一种特殊类型的数组来保存位置。Bitset中数组大小会随需要增加。这和位向量(vector of bits)比较类似。这是一个传统的类,但它在Java 2中完全重新设计。

Bitset两个构造方法。

BitSet()         //创建一个默认的对象

BitSet(int size) //指定初始大小,所有位初始化为0

BitSet常用方法

序号

方法

解释

1

void and(BitSet set)

对此目标位 set 和参数位 set 执行逻辑与操作。

2

void or(BitSet bitSet)

对此位 set 和位 set 参数执行逻辑或操作。

3

void clear( )

将此 BitSet 中的所有位设置为 false。

4

void set(int index)

将指定索引处的位设置为 true。

5

int size( )

返回此 BitSet 表示位值时实际使用空间的位数。

BitSet不常用方法

序号

方法

解释

1

void andNot(BitSet set)

清除此 BitSet 中所有的位,其相应的位在指定的 BitSet 中已设置。

2

void xor(BitSet bitSet)

对此位 set 和位 set 参数执行逻辑异或操作。

3

void clear( )

将此 BitSet 中的所有位设置为 false。

4

void clear(int index)

将索引指定处的位设置为 false。

5

void clear(int startIndex, int endIndex)

将指定的 8startIndex(包括)到指定的 toIndex(不包括)范围内的位设置为 false。

6

boolean equals(Object bitSet)

将此对象与指定的对象进行比较。

7

void set(int index, boolean v)

将指定索引处的位设置为指定的值。

8

void set(int startIndex, int endIndex)

将指定的 fromIndex(包括)到指定的 toIndex(不包括)范围内的位设置为 true。

9

void set(int startIndex, int endIndex, boolean v)

将指定的 fromIndex(包括)到指定的 toIndex(不包括)范围内的位设置为指定的值。

10

int size( )

返回此 BitSet 表示位值时实际使用空间的位数。

11

String toString( )

返回此位 set 的字符串表示形式。

示例:

import java.util.BitSet;
 
public class BitSetDemo {
 
  public static void main(String args[]) {
         BitSet bits1 = new BitSet(16);
         BitSet bits2 = new BitSet(16);
          
         // set some bits
         for(int i=0; i<16; i++) {
            if((i%2) == 0) bits1.set(i);
            if((i%6) != 0) bits2.set(i);
         }
         System.out.println("Initial pattern in bits1: ");
         System.out.println(bits1);
         System.out.println("\nInitial pattern in bits2: ");
         System.out.println(bits2);

         // AND bits
         bits2.and(bits1);
         System.out.println("\nbits2 AND bits1: ");
         System.out.println(bits2);

         // OR bits
         bits2.or(bits1);
         System.out.println("\nbits2 OR bits1: ");
         System.out.println(bits2);

         // XOR bits
         bits2.xor(bits1);
         System.out.println("\nbits2 XOR bits1: ");
         System.out.println(bits2);
  }

}

运行结果

Initial pattern in bits1: 
{0, 2, 4, 6, 8, 10, 12, 14}     这些数字表示第几位为1

Initial pattern in bits2: 
{1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15}

bits2 AND bits1: 
{2, 4, 8, 10, 14}

bits2 OR bits1:     //bits2:{2, 4, 8, 10, 14}  or  bits1:{0, 2, 4, 6, 8, 10, 12, 14}
{0, 2, 4, 6, 8, 10, 12, 14}

bits2 XOR bits1:    //bits2:{0, 2, 4, 6, 8, 10, 12, 14}  or  bits1:{0, 2, 4, 6, 8, 10, 12, 14}
{}

3 向量(Vector)

Vector底层是用数组实现的,其容量是可以动态扩展的,默认初始容量是10,默认增长因子是0,详细的扩容方式会在构造方法中讲述。

Vector对象和ArrayList一样可以随意插入不同类的对象,因为其动态扩展的特性,不需要考虑容量限制。事实上Vector与ArrayList的实现方式非常相似,但是ArrayList中的方法没有synchronized关键字修饰,而Vector类中的方法都有synchronized关键字修饰,其中的单个方法都属于原子操作,是线程安全的。

注意: 多个原子操作组成的复合操作并不是线程安全的,必须将该复合操作变成原子操作,才能保证线程安全。

然而正因为Vector类中每个方法中都添加了synchronized的关键字来保证同步,使得它的效率大大的降低了,比ArrayList的效率要慢,因此一般情况下都不使用Vector对象,而会选择使用ArrayList。

3.1 Vector类的四种构造方法

public vector() //自动对向量进行管理
public vector(int initialcapacity,int capacityIncrement) //
public vector(int initialcapacity)
public Vector(Collection c)//创建一个包含集合 c 元素的向量:

频繁地扩容容易引起效率问题,因此对于第二种和第三种构造方法,可以通过指定参数来优化向量的存储空。其中initialcapacity设定向量对象的容量(即向量对象可存储数据的大小),当真正存放的数据个数超过容量时。系统会扩充向量对象存储容量。此时参数capacityincrement就给定了每次扩充的扩充值。当capacityincrement为0的时候,则每次扩充一倍。

3.2 Vector类常用的插入方法

//将obj对象插入到向量末尾
public final synchronized boolean add(Object obj)
public final synchronized void addElement(Object obj)
    //在index指定的位置插入obj,原来对象以及此后的对象依次往后顺延。
public final synchronized void add(int index,Object obj)
//将index处的对象设置成obj,原来的对象将被覆盖。 
public final synchronized void setElementAt(Object obj,int index)

3.3 Vector类常用的删除功能

//从向量中删除obj,若有多个存在,则从向量头开始,删除找到的第一个与obj相同的向量成员
public final synchronized void removeElement(Object obj) 
//删除向量所有的对象
public final synchronized void clear(); 
public final synchronized void removeAllElement(); 
//删除index所指的地方的对象
public fianl synchronized void removeElementAt(int index) 

3.4 Vector类常用的查询搜索功能

//返回向量中指定位置的元素
public final synchronized Object get(int index) 
//从向量头开始搜索obj,返回所遇到的第一个obj对应的下标,若不存在此obj,返回-1.
public final  int indexOf(Object obj)
//从index所表示的下标处开始搜索obj
public final synchronized int indexOf(Object obj,int index)
//从向量尾部开始逆向搜索obj.
public final int lastindexOf(Object obj)
//从index所表示的下标处由尾至头逆向搜索obj
public final synchornized int lastIndex(Object obj,int index)
//获取向量对象中的首个obj 
public final synchornized firstElement()
//获取向量对象的最后一个obj
public final synchornized Object lastElement()

3.5 Vector类的其他方法

//获取向量元素的个数。它们返回值是向量中实际存在的元素个数,而非向量容量。可以调用方法capacity()来获取容量值。
public final int size(); 
//此方法用来定义向量的大小,若向量对象现有成员个数已经超过了newsize的值,则超过部分的多余元素会丢失。 
public final synchronized void setSize(int newsize);
//此方法将向量对象对应到一个枚举类型,进而可以对向量中的元素进行遍历
public final synchronized Enumeration elements(); 

3.6 Vector对象中元素常用的遍历方式

Vector hs=new Vector<>();//向量类可以指定泛型
//遍历方式1
public void printSet1(Vector hs) {
      Enumeration elements = hs.elements();
      while (elements.hasMoreElements()) {
           System.out.println(elements.nextElement());
      }
}
//遍历方式2
public void printSet2(Vector hs){
    for(int i=0;i hs){
    for(String s:hs){
        System.out.println(s);
    }
}
//遍历方式4
public void printSet4(Vector hs) {
      Iterator it = hs.iterator();
      while (it.hasNext()) {
           System.out.println(it.next());
      }
}

遍历方式示例:

public static void main(String[] args) {
    Vector hs=new Vector();
    User user=new User();
    user.setAge(12);
    user.setName("haha");
    hs.add(user);//1、先插入user对象
    boolean f=hs.add(1);//2、插入Integer对象(JDK1.5之后可以自动装箱与拆箱)
    hs.addElement("w");//3、插入String对象
    hs.add(1,"3");//4、在索引位置1处插入String对象
    System.out.println(f);//第2步操作返回boolean类型结果
    Iterator it = hs.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
    /*for(int i=0;i elements = hs.elements();
    while (elements.hasMoreElements()) {
        System.out.println(elements.nextElement());
    }*/
}

输出如下所示:

true
prac.User@7291c18f
3
1
w

4 栈(Stack)

4.1 栈(Stack)的介绍

栈是一个先入后出(FILO:First In Last Out)的有序列表。

栈(Stack)是限制线性表中元素的插入和删除只能在同一端进行的一种特殊线性表

允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)

根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶

而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除

4.2 栈(Stack)的定义

栈是Vector的一个子类,它实现了一个标准的后进先出的栈。

堆栈只定义了默认构造函数,用来创建一个空栈。堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。

import java.util.EmptyStackException;  
import java.util.Stack;  
  
/**  
* @author lin  
* @version 1.0  
* @date 2020-07-10 15:00  
* @Description TODO  
*/  
public class TestStackDemo {  
  
   static void showpush(Stack st, int a) {  
       st.push(new Integer(a));  
       System.out.println("push(" + a + ")");  
       System.out.println("stack: " + st);  
  }  
  
   static void showpop(Stack st) {  
       System.out.print("pop -> ");  
       Integer a = (Integer) st.pop();  
       System.out.println(a);  
       System.out.println("stack: " + st);  
  }  
  
   public static void main(String args[]) {  
       Stack st = new Stack();  
       System.out.println("stack: " + st);  
       showpush(st, 42);  
       showpush(st, 66);  
       showpush(st, 99);  
       showpop(st);  
       showpop(st);  
       showpop(st);  
       try {  
           showpop(st);  
      } catch (EmptyStackException e) {  
           System.out.println("empty stack");  
      }  
  }  
}

运行结果:

stack: []  
push(42)  
stack: [42]  
push(66)  
stack: [42, 66]  
push(99)  
stack: [42, 66, 99]  
pop -> 99  
stack: [42, 66]  
pop -> 66  
stack: [42]  
pop -> 42  
stack: []

4.3 栈的自定义实现

栈的实现有两种,一种是顺序栈,底层是数组;另一种是链式栈,是用链表实现的。栈的主要功能有:push(入栈)、pop(出栈)、peek(获取栈顶元素,不删除)、empty(判断栈是否为空)

4.3.1 顺序栈

使用数组实现,定义curSize记录当前数据的个数,如果空间满了,通过copyOf方法扩容

public class myStack {  
    public Object[] arr;//存放数据的数组  
    public int curSize;//当前数据的个数  
  
    public myStack() {  
        this.arr = new Object[10];  
    }  
  
    //入栈  
    public E push(E val) {  
        //满了,扩容  
        if (curSize == arr.length) {  
            this.arr = Arrays.copyOf(this.arr, 2 * this.arr.length);  
        }  
        arr[curSize] = val;  
        curSize++;  
  
        return val;//返回入栈的元素  
    }  
  
    //出栈  
    public E pop() {  
        if (empty()) {  
            //如果栈中为空  
            return null;  
        }  
        Object ret = this.arr[curSize - 1];  
        curSize--;  
        return (E) ret;//返回出栈的元素  
    }  
  
    //获取栈顶元素,不删除  
    public E peek() {  
        if (curSize == 0) {  
            return null;  
        }  
        Object ret = this.arr[curSize - 1];  
        return (E) ret;//返回栈顶元素  
    }  
  
    //判断是否为空  
    public boolean empty() {  
        return curSize == 0;  
    }  
}

4.3.2 链式栈

如果用单链表实现栈,只能在链表的头部进行操作,这样时间复杂度才为O(1); 如果使用的是双向链表,头部和尾部都可以,这里我们使用单链表实现

public class myStack {

	//链表的结点
    static class ListNode {
        public Object val;//数据
        public ListNode next;//下一个结点

        public ListNode(Object val) {
            this.val = val;
        }
    }

    public ListNode head;//(头结点)第一个结点

    //入栈
    public E push(E val) {
        ListNode newNode = new ListNode(val);
        if (head != null) {
            newNode.next = head;
        }
        head = newNode;
        return val;
    }

    //出栈
    public E pop() {
        if (head == null) {
            return null;
        }
        Object ret = head.val;

        if (head.next == null) {
            head = null;
            return (E) ret;
        }


        head = head.next;


        return (E) ret;
    }

    //获取栈顶元素
    public E peek() {
        if (head == null) {
            return null;
        }
        return (E) head.val;
    }

    //判断栈是否为空
    public boolean empty() {
        if (head == null) {
            return true;
        }
        return true;
    }

}

4.4 应用场景

1)子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。

2)处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。

3)表达式的转换中缀表达式转后缀表达式与求值(实际解决)。

4)二叉树的遍历

5)图形的深度优先(depth-first)搜索法

5 字典(Dictionary)

在Java中,Dictionary是一个抽象类,用于存储键值对数据。它提供了一种将键映射到值的数据结构。Dictionary允许通过键来访问和修改对应的值,类似于Java中的Map接口。

Dictionary类具有put(key, value)、get(key)、remove(key)等方法,可以用来存储和检索键值对数据。它是一种简单的数据结构,通常被用来实现类似于Map的功能。

需要注意的是,Dictionary是一个抽象类,不能直接实例化,需要使用它的子类Hashtable或Properties来创建对象。Hashtable是Dictionary的具体子类,实现了基本的键值对存储功能。而Properties是Hashtable的子类,主要用于处理属性文件。

Dictionary类已经过时了。在实际开发中,你可以实现Map接口来获取键/值的存储功能。

6 哈希表(Hashtable)

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

哈希表(Hashtable)是一种数据结构,可以提供快速的插入操作、删除操作和查找操作。在Java中,哈希表是通过Hashtable类实现的,它是一个老旧的类,现在已经被HashMap所取代,但Hashtable仍可以使用。

public class HashTableDemo {  
  
  public static void main(String args[]) {  
     // Create a hash map  
     Hashtable balance = new Hashtable();  
     Enumeration names;  
     String str;  
     double bal;  
  
     balance.put("Zara", new Double(3434.34));  
     balance.put("Mahnaz", new Double(123.22));  
     balance.put("Ayan", new Double(1378.00));  
     balance.put("Daisy", new Double(99.22));  
     balance.put("Qadir", new Double(-19.08));  
  
     // Show all balances in hash table.  
     names = balance.keys();  
     while(names.hasMoreElements()) {  
        str = (String) names.nextElement();  
        System.out.println(str + ": " +  
        balance.get(str));  
    }  
     System.out.println();  
     // Deposit 1,000 into Zara's account  
     bal = ((Double)balance.get("Zara")).doubleValue();  
     balance.put("Zara", new Double(bal+1000));  
     System.out.println("Zara's new balance: " +  
     balance.get("Zara"));  
  }  
}

运行结果:

以上实例编译运行结果如下:

Qadir: -19.08  
Zara: 3434.34  
Mahnaz: 123.22  
Daisy: 99.22  
Ayan: 1378.0  
  
Zara's new balance: 4434.34

7 属性(Properties)

7.1 概述

Properties 类是 Java 中用于处理配置文件的工具类,它继承自 Hashtable 类,实现了 Map 接口。

  • 主要用于读取和写入属性文件,以键值对的形式存储数据。
  • 配置文件通常以 .properties 为扩展名,其中每一行表示一个属性或配置项。

使用该类可以更好的处理文件:

  • 配置文件管理: 主要用于读取和保存应用程序的配置信息,例如数据库连接信息、用户设置等。
  • 国际化: 用于加载不同语言的资源文件,方便国际化应用程序。
  • 持久化: 可以将配置信息持久化到文件,以便下次程序启动时重新加载。

构造方法如下:

方法

表述

Properties()

创建一个没有默认值的空属性列表。

Properties(int initialCapacity)

创建一个没有默认值的空属性列表,并且初始大小容纳指定数量的元素,而无需动态调整大小。

Properties(Properties defaults)

创建具有指定默认值的空属性列表。

常用的方法如下:

返回类型

方法

表述

String

getProperty(String key) getProperty(String key, String defaultValue)

在此属性列表中搜索具有指定键的属性。

void

list(PrintStream out) list(PrintWriter out)

将此属性列表打印到指定的输出流。

void

load(InputStream inStream)

从输入字节流中读取属性列表(键和元素对)。

void

load(Reader reader)

以简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。

Object

setProperty(String key, String value)

调用 Hashtable方法 put 。

void

store(OutputStream out, String comments)

将此 Properties表中的此属性列表(键和元素对)以适合使用 load(InputStream)方法加载到 Properties表的格式写入输出流。

void

store(Writer writer, String comments)

将此 Properties表中的此属性列表(键和元素对)以适合使用 load(Reader)方法的格式写入输出字符流。

7.2 示例

当使用 Properties 类时,你可以使用上述方法来读取和写入属性。以下是这些方法的一些简单的代码示例:

1. getProperty(String key)

Properties properties = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
    properties.load(input);

    // 获取属性值
    String value = properties.getProperty("key");
    System.out.println("Value for key 'key': " + value);
} catch (IOException e) {
    e.printStackTrace();
}

2. getProperty(String key, String defaultValue)

Properties properties = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
    properties.load(input);

    // 获取属性值,如果不存在则使用默认值
    String value = properties.getProperty("nonexistentKey", "default");
    System.out.println("Value for key 'nonexistentKey': " + value);
} catch (IOException e) {
    e.printStackTrace();
}

3. list(PrintStream out) / list(PrintWriter out)

Properties properties = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
    properties.load(input);

    // 打印属性列表到控制台
    properties.list(System.out);
} catch (IOException e) {
    e.printStackTrace();
}

4. load(InputStream inStream)

Properties properties = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
    // 从输入流中读取属性列表
    properties.load(input);

    // 遍历所有键值对
    for (String key : properties.stringPropertyNames()) {
        String value = properties.getProperty(key);
        System.out.println(key + ": " + value);
    }
} catch (IOException e) {
    e.printStackTrace();
}

5. store(OutputStream out, String comments)

Properties properties = new Properties();
properties.setProperty("key1", "value1");
properties.setProperty("key2", "value2");

try (OutputStream output = new FileOutputStream("output.properties")) {
    // 将属性列表写入输出流
    properties.store(output, "Comments for the output file");
} catch (IOException e) {
    e.printStackTrace();
}

6. store(Writer writer, String comments)

Properties properties = new Properties();
properties.setProperty("key1", "value1");
properties.setProperty("key2", "value2");

try (Writer writer = new FileWriter("output.properties")) {
    // 将属性列表写入输出字符流
    properties.store(writer, "Comments for the output file");
} catch (IOException e) {
    e.printStackTrace();
}

7.3 Demo

上述的API方法可适当选择,完整的Demo可充分了解这个类的整体逻辑:

import java.io.*;
import java.util.Properties;

public class PropertiesDemo {

    public static void main(String[] args) {
        // 创建 Properties 对象
        Properties properties = new Properties();

        // 设置属性值
        properties.setProperty("username", "码农研究僧");
        properties.setProperty("password", "123456789");
        properties.setProperty("server", "https://blog.csdn.net/weixin_47872288");

        // 将属性列表写入输出流
        try (OutputStream output = new FileOutputStream("config.properties")) {
            properties.store(output, "Sample Configuration");
            System.out.println("Properties written to config.properties");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 从输入流中读取属性列表
        try (InputStream input = new FileInputStream("config.properties")) {
            properties.load(input);

            // 获取属性值
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            String server = properties.getProperty("server");

            System.out.println("Username: " + username);
            System.out.println("Password: " + password);
            System.out.println("Server: " + server);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 打印属性列表到控制台
        /**
         * -- listing properties --
         * password=123456789
         * server=https://blog.csdn.net/weixin_47872288
         * username=码农研究僧
         */
        properties.list(System.out);
    }
}

终端输出结果如下:

Properties written to config.properties
Username: aiowang
Password: 123456789
Server: http://baidu.com
-- listing properties --
password=123456789
server=http://baidu.com
username=aiowang

相关推荐

程序员请收好:10个非常有用的 Visual Studio Code 插件

一个插件列表,可以让你的程序员生活变得轻松许多。作者|Daan译者|Elle出品|CSDN(ID:CSDNnews)以下为译文:无论你是经验丰富的开发人员还是刚刚开始第一份工作的初级开发人...

PADS在WIN10系统中菜单显示不全的解决方法

决定由AD转PADS,打开发现菜单显示不正常,如下图所示:这个是由于系统的默认字体不合适导致,修改一下系统默认字体即可,修改方法如下:打开开始菜单-->所有程序-->Windows系统--...

一文讲解Web前端开发基础环境配置

先从基本的HTML语言开始学习。一个网页的所有内容都是基于HTML,为了学好HTML,不使用任何集成工具,而用一个文本编辑器,直接从最简单的HTML开始编写HTML。先在网上下载notepad++文...

TCP/IP协议栈在Linux内核中的运行时序分析

本文主要是讲解TCP/IP协议栈在Linux内核中的运行时序,文章较长,里面有配套的视频讲解,建议收藏观看。1Linux概述  1.1Linux操作系统架构简介Linux操作系统总体上由Linux...

从 Angular Route 中提前获取数据

#头条创作挑战赛#介绍提前获取意味着在数据呈现在屏幕之前获取到数据。本文中,你将学到,在路由更改前怎么获取到数据。通过本文,你将学会使用resolver,在AngularApp中应用re...

边做游戏边划水: 基于浅水方程的水面交互、河道交互模拟方法

以下文章来源于腾讯游戏学堂,作者Byreave篇一:基于浅水方程的水面交互本文主要介绍一种基于浅水方程的水体交互算法,在基本保持水体交互效果的前提下,实现了一种极简的水面模拟和物体交互方法。真实感的...

Nacos介绍及使用

一、Nacos介绍Nacos是SpringCloudAlibaba架构中最重要的组件。Nacos是一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台,提供注册中心、配置中心和动态DNS...

Spring 中@Autowired,@Resource,@Inject 注解实现原理

使用案例前置条件:现在有一个Vehicle接口,它有两个实现类Bus和Car,现在还有一个类VehicleService需要注入一个Vehicle类型的Bean:publicinte...

一文带你搞懂Vue3 底层源码

作者:妹红大大转发链接:https://mp.weixin.qq.com/s/D_PRIMAD6i225Pn-a_lzPA前言vue3出来有一段时间了。今天正式开始记录一下梗vue3.0.0-be...

一线开发大牛带你深度解析探讨模板解释器,解释器的生成

解释器生成解释器的机器代码片段都是在TemplateInterpreterGenerator::generate_all()中生成的,下面将分小节详细展示该函数的具体细节,以及解释器某个组件的机器代码...

Nacos源码—9.Nacos升级gRPC分析五

大纲10.gRPC客户端初始化分析11.gRPC客户端的心跳机制(健康检查)12.gRPC服务端如何处理客户端的建立连接请求13.gRPC服务端如何映射各种请求与对应的Handler处理类14.gRP...

聊聊Spring AI的Tool Calling

序本文主要研究一下SpringAI的ToolCallingToolCallbackorg/springframework/ai/tool/ToolCallback.javapublicinter...

「云原生」Containerd ctr,crictl 和 nerdctl 命令介绍与实战操作

一、概述作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使用,只是大部分时候我们因熟悉Docker,在部署集群时采用了默认的dockers...

在MySQL登录时出现Access denied for user ~~ (using password: YES)

Windows~~~在MySQL登录时出现Accessdeniedforuser‘root‘@‘localhost‘(usingpassword:YES),并修改MySQL密码目录适用...

mysql 8.0多实例批量部署script

背景最近一个项目上,客户需要把阿里云的rdsformysql数据库同步至线下,用作数据的灾备,需要在线下的服务器上部署mysql8.0多实例,为了加快部署的速度,写了一个脚本。解决方案#!/bi...