ollection接口 (java.util.Collection)是java集合根接口中的一個,盡管不直接實例化Collection,但是我們經常用到其子類,而且通常把其子類當做Collection使用,本文我們會講到。
正如上面所說,我們不直接實例化Collection,而是實例化其子類,下面是創建Collection子類List的代碼:
Collection collection=new ArrayList();
上面的示例適用于Collection的每個子類型。
Collection的子類接口:
Java沒有提供Collection接口的可用實現,因此必須使用列出的子類型之一。Collection接口僅僅定義了一組所有子類都共享的方法,你可以忽略它的特定類型,把它當作一個Collection來處理。這是標準的繼承,所以沒有什么神奇之處,但是它仍然可以是一個很好的特性,下文會講述這些共同的操作。
下面的代碼是使用Collection的一個方法:
public class MyCollectionUtil{
public static void doSomething(Collection collection) {
Iterator iterator=collection.iterator();
while(iterator.hasNext()){
Object object=iterator.next();
//do something to object here...
}
}
}
下面是幾種不同的Collection子類調用上面的方法:
Set set =new HashSet();
List list=new ArrayList();
MyCollectionUtil.doSomething(set);
MyCollectionUtil.doSomething(list);
無論使用Collection的哪個子類,都有標準的增加元素的方法,通過Collection的add()方法增加元素,下面是代碼:
String anElement ="an element";
Collection collection=new HashSet();
boolean didCollectionChange=collection.add(anElement);
add()方法增加指定的元素,如果Collection因調用add()方法而更改,則返回true。如果Set中已經包含了此元素,那么就不再增加,另一方面,如果是List,則List中會存在兩個同樣的元素。
remove()方法用于移除指定的元素,如果元素在Collection則會返回true,如果不存在則會返回false,下面是代碼:
boolean wasElementRemoved=collection.remove("an element");
同樣可以用Collection的addAll()方法增加另外一個Collection,下面是代碼:
Set aSet =... // get Set with elements from somewhere
Collection collection=new HashSet();
collection.addAll(aSet); //returns boolean too, but ignored here
Collection 的ddAll()方法增加參數Collection中的所有元素,但是增加的不是Collection本身僅僅是其元元素,如果使用Collection作為參數調用add(),則集合對象本身將被添加,而不是其元素。addAll()方法的具體行為取決于Collection子類型。某些Collection子類型允許將同一元素多次添加,而其他子類型則不允許。
Collection的removeAll()移除給定參數Collection中的所有元素,如果參數Collection中的元素在本身Collection中不存在,則僅僅是忽略,下面是代碼:
Collection objects=//... get a collection of objects from somewhere.
collection.removeAll(objects);
Collection 的retainAll()方法剛好和 removeAll()方法相反,不是移除所有給定參數中的Collection元素,而是保留這些元素,移除其他的元素,需要注意的是僅僅保留原Collection中存在的元素。任何在參數中存在而原Collection中不存在的元素,會被忽略,不會被增加,下面代碼:
Collection colA=new ArrayList();
Collection colB=new ArrayList();
colA.add("A");
colA.add("B");
colA.add("C");
colB.add("1");
colB.add("2");
colB.add("3");
Collection target=new HashSet();
target.addAll(colA); //target now contains [A,B,C]
target.addAll(colB); //target now contains [A,B,C,1,2,3]
target.retainAll(colB); //target now contains [1,2,3]
Collection有兩個方法可以檢查是否包含某個或者某些確定的元素, contains()和 containsAll()方法,下面是代碼:
Collection collection =new HashSet();
boolean containsElement=collection.contains("an element");
Collection elements =new HashSet();
boolean containsAll =collection.containsAll(elements);
如果Collection中包含某個元素contains() 方法會返回true,否則會返回false。
如果Collection中包含給定Collection的所有元素,那么containsAll()返回true,否則返回false。
可以調用Collection的size()方法,返回Collection中的元素個數,下面代碼:
int numberOfElements=collection.size();
可以通過Iterator迭代Collection中的所有元素,下面是代碼:
Collection collection=new HashSet();
//... add elements to the collection
Iterator iterator=collection.iterator();
while(iterator.hasNext()){
Object object=iterator.next();
System.out.println(object);
}
同樣可以通過for-each循環迭代Collection:
Collection collection=new HashSet();
collection.add("A");
collection.add("B");
collection.add("C");
for(Object object : collection) {
System.out.println(object);
}
參考:https://blog.csdn.net/cgsyck/article/details/108276863
https://blog.csdn.net/cgsyck/article/details/108292980
http://tutorials.jenkov.com/java-collections/collection.html
天我們來講講容器,何為容器?一個可以存放東西的物品。在JAVA世界里的容器,自然是能存儲數據的物品。在百度百科上是這么描述的:JAVA容器可以管理對象的生命周期、對象與對象之間的依賴關系,您可以使用一個配置文件(通常是XML),在上面定義好對象的名稱、如何產生(Prototype 方式或Singleton 方式)、哪個對象產生之后必須設定成為某個對象的屬性等,在啟動容器之后,所有的對象都可以直接取用,不用編寫任何一行程序代碼來產生對象,或是建立對象與對象之間的依賴關系。
一、java容器有哪些?
答:java容器包含List、ArrayList、Vector,Map、HashTable、HashMap、HashSet
二、Collection和Collections有什么區別?
答:最大的區別就是,前者是集合接口,后者是類,我們從源碼分析,先來一張關系圖
上面的關系圖也許看著有點暈,那我拿些源碼出來看,大家邊看圖,邊看源碼,會理解更深,今天我們就拿List做關系分解
public interface List<E> extends Collection<E>{} //List繼承Collection,看上面的繼承線
AbstractCollection抽象類實現Collection接口
public abstract class AbstractCollection<E> implements Collection<E> {}
AbstractList抽象類繼承AbstractCollection
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
ArrayList實現類繼承AbstractList抽象類并且實現List集合接口
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
Cloneable:一個標記接口,他是一個空的接口,沒有方法也沒有屬性,他的作用只是為了防止對象在調用clone克隆方法時拋出CloneNotSupportedException異常,而ArrayList這個實現類,就有一個這樣的接口。我們都知道,集合是一個可變數組,在你對集合進行增刪時,集合的內部就是一個克隆新增的操作。實現 Cloneable來表示該對象能被克隆,能使用Object.clone()方法.
RandomAccess:也是一個標記接口,代表著實現類可以調用隨機訪問的方法。
/**說明:List的clone方法 * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The * elements themselves are not copied.) * * @return a clone of this <tt>ArrayList</tt> instance */ public Object clone() { try { ArrayList<?> v=(ArrayList<?>) super.clone(); v.elementData=Arrays.copyOf(elementData, size); v.modCount=0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } }
Collection源碼:它是一個接口類,支持集合泛型,并且繼承于Iterable迭代接口。
* @param <E> the type of elements in this collection * * @author Josh Bloch * @author Neal Gafter * @see Set * @see List * @see Map * @see SortedSet * @see SortedMap * @see HashSet * @see TreeSet * @see ArrayList * @see LinkedList * @see Vector * @see Collections * @see Arrays * @see AbstractCollection * @since 1.2 */ public interface Collection<E> extends Iterable<E> { }
Collection是各集合的繼承類,如List,Set等,都繼承Collection。集合繼承了父類的迭代遍歷功能。
List源碼:
* @param <E> the type of elements in this list * * @author Josh Bloch * @author Neal Gafter * @see Collection * @see Set * @see ArrayList * @see LinkedList * @see Vector * @see Arrays#asList(Object[]) * @see Collections#nCopies(int, Object) * @see Collections#EMPTY_LIST * @see AbstractList * @see AbstractSequentialList * @since 1.2 */ public interface List<E> extends Collection<E> { }
Collection接口提供了13個功能,我們可以重寫這個接口。Collection下的集合子類都具有這些功能,大家可以看一下這些方法,是不是很熟悉,我們拿List來看,常用的如獲取集合的大小 list.size(),判斷集合長度是否為0 list.isEmpty()
public static void main(String [] args) { Collection<List> collection=new Collection<List>() { @Override public int size() { return 0; } @Override public boolean isEmpty() { return size()==0; } @Override public boolean contains(Object o) { Iterator<E> it=iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false; } @Override public Iterator<List> iterator() { return null; } @Override public Object[] toArray() { return new Object[0]; } @Override public <T> T[] toArray(T[] a) { return null; } @Override public boolean add(List list) { return false; } @Override public boolean remove(Object o) { return false; } @Override public boolean containsAll(Collection<?> c) { return false; } @Override public boolean addAll(Collection<? extends List> c) { return false; } @Override public boolean removeAll(Collection<?> c) { return false; } @Override public boolean retainAll(Collection<?> c) { return false; } @Override public void clear() { } }; }
從以上源碼可以看出,Collection是一個接口,一個集合接口的父類,從關系圖看著就像集合的祖輩。我后面會一一對Collection下的各集合接口進行源碼介紹。接著我們講講Collections。
Collections源碼:
* <p>This class is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @author Josh Bloch * @author Neal Gafter * @see Collection * @see Set * @see List * @see Map * @since 1.2 */ public class Collections { // Suppresses default constructor, ensuring non-instantiability. private Collections() { } }
Collections是一個工具類,他實現了很多集合方法,而且都是靜態多態方法。比如我們常用的排序,因為是靜態方法,所以我們不需要實例化Collections,可以直接調用,如:
public static void main(String [] args) { Collections.sort(new ArrayList<T>()); }
上面方法,是調用了List自己的默認方法,大家看到下面的語句是否會有些奇怪?前面我們分析了,List只是一個接口,ArrayList才是實現List的實現類。接口怎么能有實現方法呢?答案是JAVA8后允許接口方法有默認實現方式,從而大大提高了JAVA程序的向后兼容性問題。有興趣的可以進入List源碼看,除了兩個默認實現方法外,其他都是需要實現的接口。
default void sort(Comparator<? super E> c) { Object[] a=this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i=this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } } default void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final ListIterator<E> li=this.listIterator(); while (li.hasNext()) { li.set(operator.apply(li.next())); } }
到此,大致介紹了一下Collection和Collections的區別?,F在大家知道他倆的區別了吧?一個是集合接口,是集合的父親,下面有了堆的集合孩子。而Collections就是這些孩子的好朋友,提供了集合的了些工具,一些很方便的方法。后續我會一一帶大家進行各集合的源碼分析。讓原理實現不再神秘。最后附上一張大圖
tmlAgilityPack是一個.NET平臺下的HTML解析庫,它可以將HTML文本轉換為DOM文檔對象,方便我們對HTML文本進行操作和分析。HtmlAgilityPack支持XPath語法,可以通過XPath表達式來獲取DOM節點,同時還提供了一些方便的API,可以實現HTML文本的解析、修改、生成等功能。本文將詳細介紹HtmlAgilityPack的使用及使用方法。
一、HtmlAgilityPack的安裝
HtmlAgilityPack是一個NuGet包,可以通過Visual Studio的NuGet包管理器來安裝。具體步驟如下:
安裝完成后,就可以在項目中使用HtmlAgilityPack了。
二、HtmlAgilityPack的使用
使用HtmlAgilityPack解析HTML文本的第一步是將HTML文本加載到一個HtmlDocument對象中。可以通過以下代碼來實現:
HtmlDocument doc=new HtmlDocument();
doc.LoadHtml(htmlText);
其中,htmlText是要解析的HTML文本。LoadHtml方法會將HTML文本解析成一個DOM文檔對象,并存儲在doc對象中。
HtmlAgilityPack提供了一些方法來獲取DOM節點,例如GetElementById、GetElementsByTagName、SelectSingleNode、SelectNodes等。這些方法都接受一個XPath表達式作為參數,用來指定要獲取的節點。以下是一些示例代碼:
// 獲取id為"content"的節點
HtmlNode contentNode=doc.GetElementById("content");
// 獲取所有的a標簽
HtmlNodeCollection aNodes=doc.DocumentNode.SelectNodes("//a");
// 獲取第一個p標簽
HtmlNode pNode=doc.DocumentNode.SelectSingleNode("//p");
其中,XPath表達式的語法與XML的XPath語法相同。在這里不再詳細介紹。
HtmlAgilityPack提供了一些方法來修改DOM節點,例如SetAttributeValue、InnerHtml、OuterHtml等。以下是一些示例代碼:
// 修改id為"content"的節點的class屬性
contentNode.SetAttributeValue("class", "new-class");
// 修改第一個p標簽的內容
pNode.InnerHtml="這是新的內容";
// 修改第一個a標簽的href屬性
HtmlNode aNode=aNodes[0];
aNode.SetAttributeValue("href", "http://www.example.com");
HtmlAgilityPack還可以將DOM文檔對象轉換為HTML文本??梢酝ㄟ^以下代碼來實現:
string newHtmlText=doc.DocumentNode.OuterHtml;
其中,OuterHtml屬性返回DOM文檔對象的HTML文本表示。
三、HtmlAgilityPack的功能實例
下面將通過一些具體的實例來演示HtmlAgilityPack的使用方法。
以下代碼演示了如何獲取頁面標題:
HtmlDocument doc=new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNode titleNode=doc.DocumentNode.SelectSingleNode("//title");
string title=titleNode.InnerHtml;
其中,htmlText是要解析的HTML文本。首先,將HTML文本加載到一個HtmlDocument對象中。然后,通過XPath表達式“//title”獲取頁面標題節點。最后,通過InnerHtml屬性獲取標題的內容。
以下代碼演示了如何獲取頁面中的所有圖片:
HtmlDocument doc=new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNodeCollection imgNodes=doc.DocumentNode.SelectNodes("//img");
foreach (HtmlNode imgNode in imgNodes)
{
string src=imgNode.GetAttributeValue("src", "");
Console.WriteLine(src);
}
首先,將HTML文本加載到一個HtmlDocument對象中。然后,通過XPath表達式“//img”獲取所有圖片節點。最后,遍歷所有圖片節點,獲取每個節點的src屬性。
以下代碼演示了如何獲取頁面中的所有鏈接:
HtmlDocument doc=new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNodeCollection aNodes=doc.DocumentNode.SelectNodes("//a");
foreach (HtmlNode aNode in aNodes)
{
string href=aNode.GetAttributeValue("href", "");
Console.WriteLine(href);
}
首先,將HTML文本加載到一個HtmlDocument對象中。然后,通過XPath表達式“//a”獲取所有鏈接節點。最后,遍歷所有鏈接節點,獲取每個節點的href屬性。
以下代碼演示了如何將頁面中的所有鏈接修改為指定的鏈接:
HtmlDocument doc=new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNodeCollection aNodes=doc.DocumentNode.SelectNodes("//a");
foreach (HtmlNode aNode in aNodes)
{
aNode.SetAttributeValue("href", "http://www.example.com");
}
string newHtmlText=doc.DocumentNode.OuterHtml;
首先,將HTML文本加載到一個HtmlDocument對象中。然后,通過XPath表達式“//a”獲取所有鏈接節點。最后,遍歷所有鏈接節點,將它們的href屬性修改為指定的鏈接。最后,通過OuterHtml屬性將修改后的DOM文檔對象轉換為HTML文本。
本文介紹了HtmlAgilityPack的使用及使用方法。HtmlAgilityPack是一個功能強大、易用性高的HTML解析庫,可以方便地對HTML文本進行操作和分析。通過本文的介紹,讀者可以了解HtmlAgilityPack的基本用法,并可以根據需要自行擴展。
【大廠面試】Java中的序列化和反序列化它們的作用和用途是什么?
.net core下優秀的日志框架使用解析,附源代碼
Spring Boot+Vue全棧開發實戰,中文版高清PDF資源
作者簡介:
【架構師老盧】20年資深軟件架構師,分享編程、軟件設計經驗,教授前沿技術,分享技術資源,分享職場感悟
*請認真填寫需求信息,我們會在24小時內與您取得聯系。