欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java集合教程之Collection實(shí)例詳解

 更新時(shí)間:2018年08月19日 09:21:25   作者:YJK923  
集合,或者叫容器,是一個(gè)包含多個(gè)元素的對(duì)象,下面這篇文章主要給大家介紹了關(guān)于Java集合教程之Collection的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

集合就是一組數(shù)的集合,就像是一個(gè)容器,但是我們應(yīng)該清楚的是集合中存放的都是對(duì)象的引用,而不是真正的實(shí)體。而我們常說的集合中的對(duì)象其實(shí)指的就是對(duì)象的引用。

我們可以把集合理解為一個(gè)小型數(shù)據(jù)庫,用于存放數(shù)據(jù),我們對(duì)集合的操作也就是數(shù)據(jù)的增刪改查,在 Java 中有兩個(gè)頂層接口 Collection 和 Map 用于定義和規(guī)范集合的相關(guān)操作。這篇文章主要說一下集合框架中的 Collection 部分。

Collection 表示一組對(duì)象,這些對(duì)象可以是有序也可以是無序的,它提供了不同的子接口滿足我們的需求。我們主要看看 List 和 Set 。

 

List 整體的特征就是有序可重復(fù)。我們需要研究的是上圖中具體的實(shí)現(xiàn)類都有什么特性。底層的實(shí)現(xiàn)原理是什么,首先來看一看 List 的古老的實(shí)現(xiàn)類 Vector ,說是古老是因?yàn)樵?JDK 1.0 的時(shí)候就出現(xiàn)了,都走開,我要開始看源碼了!這些源碼來自于 JDK 1.7。

public class Vector<E>
 extends AbstractList<E>
 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
 /**
  * The array buffer into which the components of the vector are
  * stored.
  */
 protected Object[] elementData;

 /**
  * The number of valid components in this {@code Vector} object.
  */
 protected int elementCount;

 /**
  * The amount by which the capacity of the vector is automatically
  * incremented when its size becomes greater than its capacity. If
  * the capacity increment is less than or equal to zero, the capacity
  * of the vector is doubled each time it needs to grow.
  */
 protected int capacityIncrement;

 public Vector() {
  this(10);
 }

 // 添加元素
 public synchronized boolean add(E e) {
  modCount++;
  ensureCapacityHelper(elementCount + 1);
  elementData[elementCount++] = e;
  return true;
 }

 // 刪除元素
 public synchronized E remove(int index) {
  modCount++;
  if (index >= elementCount)
   throw new ArrayIndexOutOfBoundsException(index);
  E oldValue = elementData(index);

  int numMoved = elementCount - index - 1;
  if (numMoved > 0)
   System.arraycopy(elementData, index+1, elementData, index,
        numMoved);
  elementData[--elementCount] = null; // Let gc do its work

  return oldValue;
 }

 // 修改元素
 public synchronized E set(int index, E element) {
  if (index >= elementCount)
   throw new ArrayIndexOutOfBoundsException(index);

  E oldValue = elementData(index);
  elementData[index] = element;
  return oldValue;
 }
 // 查找元素
 public synchronized E get(int index) {
  if (index >= elementCount)
   throw new ArrayIndexOutOfBoundsException(index);

  return elementData(index);
 }
...

就以上源碼分析就可以知道關(guān)于 Vector 的特征。1 底層實(shí)現(xiàn)是使用數(shù)組來存儲(chǔ)數(shù)據(jù),所以相應(yīng)的查找元素和添加元素速度較快,刪除和插入元素較慢。2 數(shù)組的初始長度為 10 ,當(dāng)長度不夠時(shí),增長量也為 10 使用變量 capacityIncrement 來表示。3 方法的聲明中都加入了 synchronized 關(guān)鍵字,線程安全的,所以效率相應(yīng)降低了。 4 沒分析出來的再看一遍。

下面開始看 ArrayList 的源碼。

public class ArrayList<E> extends AbstractList<E>
  implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
 private static final long serialVersionUID = 8683452581122892189L;

 /**
  * Default initial capacity.
  */
 private static final int DEFAULT_CAPACITY = 10;

 /**
  * Shared empty array instance used for empty instances.
  */
 private static final Object[] EMPTY_ELEMENTDATA = {};

 /**
  * The array buffer into which the elements of the ArrayList are stored.
  * DEFAULT_CAPACITY when the first element is added.
  */
 private transient Object[] elementData;

 /**
  * Constructs an empty list with an initial capacity of ten.
  */
 public ArrayList() {
  super();
  this.elementData = EMPTY_ELEMENTDATA;
 }

 // 添加元素
 public boolean add(E e) {
  ensureCapacityInternal(size + 1); // Increments modCount!!
  elementData[size++] = e;
  return true;
 }

 // 增加數(shù)組的長度
 private void grow(int minCapacity) {
  // overflow-conscious code
  int oldCapacity = elementData.length;
  int newCapacity = oldCapacity + (oldCapacity >> 1);
  if (newCapacity - minCapacity < 0)
   newCapacity = minCapacity;
  if (newCapacity - MAX_ARRAY_SIZE > 0)
   newCapacity = hugeCapacity(minCapacity);
  // minCapacity is usually close to size, so this is a win:
  elementData = Arrays.copyOf(elementData, newCapacity);
 }
...

因?yàn)樵创a和 Vector 類似,所以有些就不貼了,但是不耽誤我們繼續(xù)分析 ArrayList 。1 底層存儲(chǔ)數(shù)據(jù)使用的還是數(shù)組,長度依舊為 10 ,但是進(jìn)步了,沒有在剛開始創(chuàng)建的時(shí)候就初始化,而是在添加第一個(gè)元素的時(shí)候才初始化的。2 方法的聲明少了 synchronized 關(guān)鍵字,線程不安全,但性能提高了。3 數(shù)組長度不夠時(shí),會(huì)自動(dòng)增加為原長度的 1.5 倍。

以上分析也能體現(xiàn)出 Vector 和 ArrayList 的差別。主要就是想說 Vector 已經(jīng)不用了。使用 ArrayList 即可,關(guān)于線程安全問題,后面再說。

接著看 LinkedList 的實(shí)現(xiàn),上源碼 ~

public class LinkedList<E>
 extends AbstractSequentialList<E>
 implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
 transient int size = 0;

 /**
  * Pointer to first node.
  */
 transient Node<E> first;

 /**
  * Pointer to last node.
  */
 transient Node<E> last;

 /**
  * Constructs an empty list.
  */
 public LinkedList() {
 }

 // 每一個(gè)元素即為一個(gè)節(jié)點(diǎn),節(jié)點(diǎn)的結(jié)構(gòu)如下(這是一個(gè)內(nèi)部類?。?
 private static class Node<E> {
  E item;
  Node<E> next;
  Node<E> prev;

  Node(Node<E> prev, E element, Node<E> next) {
   this.item = element;
   this.next = next;
   this.prev = prev;
  }
 }

 // 添加元素
 public boolean add(E e) {
  linkLast(e);
  return true;
 }

 void linkLast(E e) {
  final Node<E> l = last;
  final Node<E> newNode = new Node<>(l, e, null);
  last = newNode;
  if (l == null)
   first = newNode;
  else
   l.next = newNode;
  size++;
  modCount++;
 }

 // 刪除某個(gè)節(jié)點(diǎn)的邏輯
 E unlink(Node<E> x) {
  // assert x != null;
  final E element = x.item;
  final Node<E> next = x.next;
  final Node<E> prev = x.prev;

  if (prev == null) {
   first = next;
  } else {
   prev.next = next;
   x.prev = null;
  }

  if (next == null) {
   last = prev;
  } else {
   next.prev = prev;
   x.next = null;
  }

  x.item = null;
  size--;
  modCount++;
  return element;
 }
...

重點(diǎn)就是 LinkedList 的底層實(shí)現(xiàn)是雙鏈表。這樣就會(huì)有以下特性,1 查找元素較慢,但是添加和刪除較快。2 占內(nèi)存,因?yàn)槊恳粋€(gè)節(jié)點(diǎn)都要維護(hù)兩個(gè)索引。3 線程不安全 。4 對(duì)集合長度沒有限制。

以上,List 的幾個(gè)實(shí)現(xiàn)已經(jīng)分析完成,以后再談到 Vector ,ArrayList ,LinkedList 之間的區(qū)別應(yīng)該不會(huì)不知所云了吧!還要接著看 Collection 的另一個(gè)子接口 Set 。首先有個(gè)大前提,Set 中存儲(chǔ)的元素是無序不可重復(fù)的。然后我們再來看實(shí)現(xiàn)類是如何實(shí)現(xiàn)的。下面開始 HashSet 的表演。

public class HashSet<E>
 extends AbstractSet<E>
 implements Set<E>, Cloneable, java.io.Serializable
{
 private transient HashMap<E,Object> map;

 // Dummy value to associate with an Object in the backing Map
 private static final Object PRESENT = new Object();

 /**
  * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
  * default initial capacity (16) and load factor (0.75).
  */
 public HashSet() {
  map = new HashMap<>();
 }

 // 添加元素,其實(shí)就是像 Map 中添加主鍵,所以添加的元素不能重復(fù)
 public boolean add(E e) {
  return map.put(e, PRESENT)==null;
 }

 // 實(shí)現(xiàn) Iterable 接口中的 Iterator 方法。
 public Iterator<E> iterator() {
  return map.keySet().iterator();
 }
...

看了源碼才發(fā)現(xiàn),1 原來 HashSet 就是對(duì) HashMap 的封裝啊,底層實(shí)現(xiàn)是基于 hash 表的,回頭有必要再好好的介紹一下 hash 相關(guān)的知識(shí)。2 Set 集合中的值,都會(huì)以 key 的形式存放在 Map 中,所以說 Set 中的元素不能重復(fù)。3 線程不安全。4 允許存放空值,因?yàn)?Map 的鍵允許為空。

今天要說的最后一個(gè)實(shí)現(xiàn)類終于出現(xiàn)啦,他就是 TreeSet ,這個(gè)實(shí)現(xiàn)類中的元素是有序的!注意這里說的有序是指按照一定的規(guī)則排序,而我們說 Set 集合中的元素?zé)o序是因?yàn)樘砑舆M(jìn)集合的順序和輸出的順序不保證一致。TreeSet 是怎么保證有序我們待會(huì)再說,還是一樣的套路,是對(duì) TreeMap 的封裝,線程依舊不安全。

public class TreeSet<E> extends AbstractSet<E>
 implements NavigableSet<E>, Cloneable, java.io.Serializable
{
 /**
  * The backing map.
  */
 private transient NavigableMap<E,Object> m;

 // Dummy value to associate with an Object in the backing Map
 private static final Object PRESENT = new Object();

 /**
  * Constructs a set backed by the specified navigable map.
  */
 TreeSet(NavigableMap<E,Object> m) {
  this.m = m;
 }

 /**
  * Constructs a new, empty tree set, sorted according to the
  * natural ordering of its elements. All elements inserted into
  * the set must implement the Comparable interface.
  */
 public TreeSet() {
  this(new TreeMap<E,Object>());
 }

 /**
  * Constructs a new, empty tree set, sorted according to the specified
  * comparator. All elements inserted into the set must be mutually
  * comparable by the specified comparator
  * If the Comparable natural ordering of the elements will be used.
  */
 public TreeSet(Comparator<? super E> comparator) {
  this(new TreeMap<>(comparator));
 }
 
 // 添加元素方法
 public boolean add(E e) {
  return m.put(e, PRESENT)==null;
 } 
...

我們可以看到 TreeSet 中構(gòu)造函數(shù)上方的注釋,TreeSet 要保證元素有序,保證有序的思路是在添加元素的時(shí)候進(jìn)行比較。

... // 這是 TreeMap 的 put 方法的節(jié)選,為了看到比較的過程。
 public V put(K key, V value) {
 ...
  // split comparator and comparable paths
  Comparator<? super K> cpr = comparator;
  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
     return t.setValue(value);
   } while (t != null);
  }
  else {
   if (key == null)
    throw new NullPointerException();
   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);
  }
 ...
 }

Java 中提供了兩種方式,第一種方法,需要我們所添加對(duì)象的類實(shí)現(xiàn) Comparable 接口,進(jìn)而實(shí)現(xiàn) compareTo 方法,這種方式也叫自然排序,我們并沒有傳入什么排序規(guī)則。這種方式對(duì)應(yīng) TreeSet 的空參構(gòu)造器。而另一種方式就是定制排序,即我們自己定義兩個(gè)元素的排序規(guī)則,在實(shí)例化 TreeSet 的時(shí)候傳入對(duì)應(yīng)的排序規(guī)則即可,對(duì)應(yīng)于 TreeSet 中帶有 Comparator 接口的構(gòu)造器,這里面需要實(shí)現(xiàn) compare 方法 。有點(diǎn)迷糊了是吧,舉個(gè)例子看看 ~

public class Person implements Comparable<Person>{

 public String name;
 public Integer age;

 public Person(String name,Integer age) {
  this.name = name;
  this.age = age;
 }
 /* 自定義的比較的邏輯:
  *  首先按照對(duì)象的 name 屬性排序
  *  其次按照 age 屬性排序
  * 方法的返回值為 0 ,大于 0,小于 0 ,分別對(duì)應(yīng)于 相等,大于,和小于
  */
 @Override
 public int compareTo(Person o) {
  int i = this.name.compareTo(o.name);
  if(i == 0){
   return this.age.compareTo(o.age);
  }else {
   return i;
  }
 }
 @Override
 public String toString() {
  return "[Person] name:"+this.name+" age:"+this.age;
 }
}

 // 以下是測試代碼
 public static void main(String[] args) {
  TreeSet<Person> set = new TreeSet<>();
  set.add(new Person("AJK923",20));
  set.add(new Person("BJK923",20));
  set.add(new Person("AJK923",21));
  set.add(new Person("BJK923",21));

  for (Person person : set) {
   System.out.println(person.toString());
  }
  /*
  [Person] name:AJK923 age:20
  [Person] name:AJK923 age:21
  [Person] name:BJK923 age:20
  [Person] name:BJK923 age:21
  */
    
  ----以下為定制排序的部分----匿名內(nèi)部類實(shí)現(xiàn) Comparator 接口----  
  TreeSet<Person> set2 = new TreeSet<>(new Comparator<Person>() {
   @Override
   public int compare(Person o1, Person o2) {
    int i = o1.age.compareTo(o2.age);
    if(i == 0){
     return o1.name.compareTo(o2.name);
    }else {
     return i;
    }
   }
  });

  set2.add(new Person("AJK923",20));
  set2.add(new Person("BJK923",20));
  set2.add(new Person("AJK923",21));
  set2.add(new Person("BJK923",21));

  for (Person person : set2) {
   System.out.println(person.toString());
  }
  /*
   [Person] name:AJK923 age:20
   [Person] name:BJK923 age:20
   [Person] name:AJK923 age:21
   [Person] name:BJK923 age:21
   */
 }

上面就是自然排序和定制排序的應(yīng)用。要說明幾點(diǎn):

1 定制排序和自然排序同時(shí)存在的話,優(yōu)先執(zhí)行定制排序??梢钥纯瓷厦娴?put 方法的實(shí)現(xiàn) 。

2 自然排序?qū)?yīng) Comparable 接口,定制排序?qū)?yīng) Comparator 接口。

3 String ,包裝類,日期類都已經(jīng)實(shí)現(xiàn)了 Comparable 接口的 comparaTo 方法,所以我上面的例子中都偷懶了,沒有自己實(shí)現(xiàn)具體比較,而是直接調(diào)用現(xiàn)成的。

看到這里,也算是對(duì) Collection 有了整體的認(rèn)識(shí),但是這里我并沒有說到具體的 API ,我現(xiàn)在日常也用不到幾個(gè)方法,就放一張 Collection 接口的結(jié)構(gòu)圖吧,方法也比較簡單,看個(gè)名字就大概知道什么意思了。

還是要重點(diǎn)說一下 iterator 方法。這個(gè)方法定義在 Iterable 接口中(Collection 繼承了 Iterable 接口),方法返回的是 iterator 接口對(duì)象。iterator 中定義了迭代器的操作規(guī)則,而 Collection 的實(shí)現(xiàn)類中是具體的實(shí)現(xiàn)。Iterator 接口中定義了 next ,hasNext 和 remove 方法??匆幌略贏rrayList 中是如何實(shí)現(xiàn)的吧。

private class Itr implements Iterator<E> {
  int cursor;  // index of next element to return
  int lastRet = -1; // index of last element returned; -1 if no such
  int expectedModCount = modCount;

  public boolean hasNext() {
   return cursor != size;
  }

  @SuppressWarnings("unchecked")
  public E next() {
   checkForComodification();
   int i = cursor;
   if (i >= size)
    throw new NoSuchElementException();
   Object[] elementData = ArrayList.this.elementData;
   if (i >= elementData.length)
    throw new ConcurrentModificationException();
   cursor = i + 1;
   return (E) elementData[lastRet = i];
  }

  public void remove() {
   if (lastRet < 0)
    throw new IllegalStateException();
   checkForComodification();

   try {
    ArrayList.this.remove(lastRet);
    cursor = lastRet;
    lastRet = -1;
    expectedModCount = modCount;
   } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
   }
  }

  final void checkForComodification() {
   if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
  }
 }

應(yīng)用起來還是比較簡單的,使用一個(gè) while 循環(huán)即可??聪旅孢@個(gè)例子。

  public static void main(String[] args) {

  List<Integer> list = new ArrayList<>(); 
  list.add(1);
  list.add(2);
  list.add(3);

  Iterator<Integer> it = list.iterator();
  while (it.hasNext()) {
   Integer i = it.next();
   System.out.println(i);
  }
 }

不知道你有沒有發(fā)現(xiàn),除了 Vector 以外,保存集合元素的那個(gè)變量都定義為 transient 不管你是數(shù)組,Node 或是 Map ,不由得我又要想一想為什么這樣設(shè)計(jì)?

先看一下 transient 的作用吧!Java 的 serialization 提供了一種持久化對(duì)象實(shí)例的機(jī)制。當(dāng)持久化對(duì)象時(shí),可能有一個(gè)特殊的對(duì)象數(shù)據(jù)成員,我們不想用 serialization 機(jī)制來保存它。為了在一個(gè)特定對(duì)象的一個(gè)域上關(guān)閉 serialization,可以在這個(gè)域前加上關(guān)鍵字 transient 。當(dāng)一個(gè)對(duì)象被序列化的時(shí)候,transient 型變量的值不包括在序列化的表示中,非 transient 型的變量是被包括進(jìn)去的。

那么為什么要這么做呢,好好的標(biāo)準(zhǔn)序列化不用,原因如下:

對(duì)于 ArrayList 來說,底層實(shí)現(xiàn)是數(shù)組,而數(shù)組的長度和容量不一定相等,可能容量為 10 ,而我們的元素只有 5 。此時(shí)序列化的時(shí)候就有點(diǎn)浪費(fèi)資源,序列化和反序列化還是要的,故 ArrayList 自己實(shí)現(xiàn)了兩個(gè)方法,分別是 writeObject 和 readObject ,用于序列化和反序列化。

對(duì)于 HashSet 和  HashMap 來說,底層實(shí)現(xiàn)都是依賴于 hash 表,而不同的 JVM 可能算出的 hashCode 值不一致,這樣在跨平臺(tái)的時(shí)候就會(huì)導(dǎo)致序列化紊亂。故也重寫了那兩個(gè)方法。借用一句似懂非懂的話:

當(dāng)一個(gè)對(duì)象的物理表示方法與它的邏輯數(shù)據(jù)內(nèi)容有實(shí)質(zhì)性差別時(shí),使用默認(rèn)序列化形式有 N 種缺陷,所以應(yīng)該盡可能的根據(jù)實(shí)際情況重寫序列化方法。

對(duì)應(yīng)于 Collection ,有一個(gè) Collections 工具類,其中提供很多方法,比如說集合的排序,求子集合,最大值,最小值,交換,填充,打亂集合等等,還記得上面說到的實(shí)現(xiàn)類中存在線程不安全的情況吧,這個(gè)工具類中提供很多對(duì)應(yīng)的 synchronized 的方法。

后記 :不知不覺中擴(kuò)展了這么多知識(shí)點(diǎn),實(shí)話說,肯定還有遺漏的地方,就我現(xiàn)在能想到的依然還有很多,除去 Hash 表和 Hash 算法這一部分之外,我還沒有對(duì)底層的數(shù)據(jù)結(jié)構(gòu)進(jìn)一步分析,數(shù)組,鏈表,二叉樹等等,現(xiàn)在是分析不動(dòng)了,本文已經(jīng)很長了。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • idea不能自動(dòng)補(bǔ)全yml配置文件的原因分析

    idea不能自動(dòng)補(bǔ)全yml配置文件的原因分析

    這篇文章主要介紹了idea不能自動(dòng)補(bǔ)全yml配置文件的原因,通過添加yml文件為配置文件能夠很快的解決,具體解決步驟跟隨小編一起通過本文學(xué)習(xí)下吧
    2021-06-06
  • 淺談單例模式和線程安全問題

    淺談單例模式和線程安全問題

    這篇文章主要介紹了淺談單例模式和線程安全問題,再某些特殊的情況下,存在一個(gè)類僅能用來產(chǎn)生一個(gè)唯一對(duì)象的必要性,因此需要單例模式,需要的朋友可以參考下
    2023-04-04
  • Java優(yōu)秀類庫Hutool使用示例

    Java優(yōu)秀類庫Hutool使用示例

    Hutool是一個(gè)小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關(guān)API的學(xué)習(xí)成本,提高工作效率,涵蓋了Java開發(fā)開發(fā)中的方方面面,使用Hutool可節(jié)省開發(fā)人員對(duì)項(xiàng)目中公用類和公用工具方法的封裝時(shí)間,使開發(fā)專注于業(yè)務(wù),同時(shí)可以最大限度的避免封裝不完善帶來的bug
    2023-02-02
  • 合并有序數(shù)組的實(shí)現(xiàn)(java與C語言)

    合并有序數(shù)組的實(shí)現(xiàn)(java與C語言)

    這篇文章主要介紹了合并有序數(shù)組的實(shí)現(xiàn)(java與C語言)的相關(guān)資料,這里對(duì)有序數(shù)組的合并分享了java版本和C語言版本的示例,需要的朋友可以參考下
    2017-08-08
  • 關(guān)于maven依賴 ${xxx.version}報(bào)錯(cuò)問題

    關(guān)于maven依賴 ${xxx.version}報(bào)錯(cuò)問題

    這篇文章主要介紹了關(guān)于maven依賴 ${xxx.version}報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • SpringBoot事務(wù)不回滾的解決方案

    SpringBoot事務(wù)不回滾的解決方案

    這篇文章主要介紹了SpringBoot事務(wù)不回滾的解決方案的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Java ByteBuffer網(wǎng)絡(luò)編程用法實(shí)例解析

    Java ByteBuffer網(wǎng)絡(luò)編程用法實(shí)例解析

    這篇文章主要介紹了Java ByteBuffer網(wǎng)絡(luò)編程用法實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • springboot中關(guān)于classpath:路徑使用及說明

    springboot中關(guān)于classpath:路徑使用及說明

    這篇文章主要介紹了springboot中關(guān)于classpath:路徑使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Java常用排序算法及性能測試集合

    Java常用排序算法及性能測試集合

    周末天氣不好,在家無事,把常用排序算法理了一遍,收獲不小,特寫文章紀(jì)念。這些算法在學(xué)校的時(shí)候?qū)W過一遍,很多原理都忘記了
    2013-06-06
  • Java基于Javafaker生成測試數(shù)據(jù)

    Java基于Javafaker生成測試數(shù)據(jù)

    這篇文章主要介紹了Java基于Javafaker生成測試數(shù)據(jù)的方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12

最新評(píng)論