最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的CollectionUtils工具類詳解

 更新時(shí)間:2023年05月16日 10:46:43   作者:逆流°只是風(fēng)景-bjhxcc  
這篇文章主要介紹了Java的CollectionUtils工具類詳解,CollectionUtils工具類是在apache下的,而不是springframework下的,個(gè)人覺(jué)得在真實(shí)項(xiàng)目中CollectionUtils,可以使你的代碼更加簡(jiǎn)潔和安全,需要的朋友可以參考下

CollectionUtils工具類是在apache下的,而不是springframework下的CollectionUtils 個(gè)人覺(jué)得在真實(shí)項(xiàng)目中CollectionUtils,可以使你的代碼更加簡(jiǎn)潔和安全 下面我們就一起來(lái)探究一下 先從maven官方找到最新jar包如下:

  <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>

一、API常用方法

 /** 1、除非元素為null,否則向集合添加元素 */ 
CollectionUtils.addIgnoreNull(personList,null); 
/** 2、將兩個(gè)已排序的集合a和b合并為一個(gè)已排序的列表,以便保留元素的自然順序 */ 
CollectionUtils.collate(Iterable<? extends O> a, Iterable<? extends O> b) 
/** 3、將兩個(gè)已排序的集合a和b合并到一個(gè)已排序的列表中,以便保留根據(jù)Comparator c的元素順序。 */ 
CollectionUtils.collate(Iterable<? extends O> a, Iterable<? extends O> b, Comparator<? super O> c) 
/** 4、返回該個(gè)集合中是否含有至少有一個(gè)元素 */ 
CollectionUtils.containsAny(Collection<?> coll1, T... coll2) 
/** 5、如果參數(shù)是null,則返回不可變的空集合,否則返回參數(shù)本身。(很實(shí)用 ,最終返回List EMPTY_LIST = new EmptyList<>()) */ 
CollectionUtils.emptyIfNull(Collection<T> collection) 
/** 6、空安全檢查指定的集合是否為空 */ 
CollectionUtils.isEmpty(Collection <?> coll) 
/** 7、 空安全檢查指定的集合是否為空。 */ 
CollectionUtils.isNotEmpty(Collection <?> coll) 
/** 8、反轉(zhuǎn)給定數(shù)組的順序。 */ 
CollectionUtils.reverseArray(Object[] array); 
/** 9、差集 */ 
CollectionUtils.subtract(Iterable<? extends O> a, Iterable<? extends O> b) 
/** 10、并集 */
 CollectionUtils.union(Iterable<? extends O> a, Iterable<? extends O> b) 
/** 11、交集 */ 
CollectionUtils.intersection(Collection a, Collection b) 
/** 12、 交集的補(bǔ)集(析?。?*/
 CollectionUtils.disjunction(Collection  a, Collection b)

二、非對(duì)象集合交、并、差處理

對(duì)于集合取交集、并集的處理其實(shí)有很多種方式,這里就介紹3種

  • 第一種 是CollectionUtils工具類
  • 第二種 是List自帶方法
  • 第三種 是JDK1.8 stream新特性

1、CollectionUtils工具類

下面對(duì)于基本數(shù)據(jù)(包括String)類型中的集合進(jìn)行demo示例

 public static void main(String[] args) {
        String[] arrayA = new String[]{"1","2","3","4"};
        String[] arrayB = new String[]{"3","4","5","6"};
        List<String> listA = Arrays.asList(arrayA);
        List<String> listB = Arrays.asList(arrayB); //1、并集 union
       System.out.println(CollectionUtils.union(listA,listB)); //輸出:[1, 2, 3, 4, 5, 6] //2、交集intersection
       System.out.println(CollectionUtils.intersection(listA,listB)); //輸出:[3, 4] //3、交集的補(bǔ)集(析取)disjunction
       System.out.println(CollectionUtils.disjunction(listA,listB)); //輸出:[1, 2, 5, 6] //4、差集(扣除)
       System.out.println(CollectionUtils.subtract(listA,listB)); //[1, 2]
}

2、List自帶方法

 public static void main(String[] args) {
        String[] arrayA = new String[]{"1","2","3","4"};
        String[] arrayB = new String[]{"3","4","5","6"};
        List<String> listA = Arrays.asList(arrayA);
        List<String> listB = Arrays.asList(arrayB); //1交集
        List<String> jiaoJiList = new ArrayList<>(listA);
        jiaoJiList.retainAll(listB);
        System.out.println(jiaoJiList); //輸出:[3, 4] //2差集
        List<String> chaJiList = new ArrayList<>(listA);
        chaJiList.removeAll(listB);
        System.out.println(chaJiList); //輸出:[1, 2] //3并集(先做差集在做添加所有)
        List<String> bingList = new ArrayList<>(listA);
        bingList.removeAll(listB);//[1,2]
        bingList.addAll(listB);//[3,4,5,6]
        System.out.println(bingList); //輸出:[1, 2, 3, 4, 5, 6]
}

注意:intersection和retainAll的差別

要注意的是它們返回類型是不一樣的,intersection返回的是一個(gè)新的List集合,而retainAll返回是Bollean類型就說(shuō)明retainAll方法是對(duì)原有集合進(jìn)行處理再返回原有集合,會(huì)改變?cè)屑现械膬?nèi)容

  • 1:從性能角度來(lái)考慮的話,List自帶會(huì)高點(diǎn),因?yàn)樗挥迷賱?chuàng)建新的集合,
  • 2:需要注意的是,因?yàn)閞etainAll因?yàn)闀?huì)改變?cè)屑?,所以該集合需要多次使用就不適合用retainAll

注意:Arrays.asList將數(shù)據(jù)轉(zhuǎn)集合不能進(jìn)行add和remove操作

原因:調(diào)用Arrays.asList()生產(chǎn)的List的add、remove方法時(shí)報(bào)異常,這是由Arrays.asList()返回的是Arrays的內(nèi)部類ArrayList,而不是java.util.ArrayList.Arrays的內(nèi)部類ArrayList和java.util.ArrayList都是繼承AbstractList,remove,add

等方法AbstractList中是默認(rèn)throw UnsupportedOperationException而且不做任何操作,java.util.ArrayList重新了這些方法而Arrays的內(nèi)部類沒(méi)有重新,所以會(huì)拋出異常

所以正確做法如下:

String[] array = {“1”,“2”,“3”}; List list = Arrays.asList(array); List arrList = new ArrayList(list); arrList.add(“4”);

3、JDK1.8 stream新特性

public static void main(String[] args) {
        String[] arrayA=new String[]{"1","2","3","4"};
        String[] arrayB=new String[]{"3","4","5","6"};
        List<String> listA = Arrays.asList(arrayA);
        List<String> listB = Arrays.asList(arrayB); //交集
        List<String> intersection = listA.stream().filter(item -> listB.contains(item)).collect(Collectors.toList());
        System.out.println(intersection); //輸出:[3, 4] //并集(新建集合:1、是因?yàn)椴挥绊懺技希?、    Arrays.asList不能add和remove操作)
        List<String> listAll = listA.parallelStream().collect(Collectors.toList());
        List<String> listAll2 = listB.parallelStream().collect(Collectors.toList());
        listAll.addAll(listAll2);
        System.out.println(listAll); //輸出:[1, 2, 3, 4, 3, 4, 5, 6] //差集
        List<String> reduceList = listA.stream().filter(item -> !listB.contains(item)).collect(Collectors.toList());
        System.out.println(reduceList); //輸出:[1, 2] //去重并集
        ArrayList<String> list = new ArrayList<>(listA);
        list.addAll(listB);
        List<String> listAllDistinct = list.stream().distinct().collect(Collectors.toList());
        System.out.println(listAllDistinct); //輸出:[1, 2, 3, 4, 5, 6]
}

總結(jié):三種方式,第一種稍微好用一些,第二種還需要確定該集合是否被多次調(diào)用,第三種可讀性不高

三、對(duì)象集合交、并、差處理 |

因?yàn)閷?duì)象的equals比較是比較兩個(gè)對(duì)象的內(nèi)存地址,所以除非是同一對(duì)象,否則equals返回的永遠(yuǎn)是false

但實(shí)際開(kāi)發(fā)中,業(yè)務(wù)系統(tǒng)中判斷對(duì)象有時(shí)候需要的不是一種嚴(yán)格意義上的相等,而是業(yè)務(wù)上的對(duì)象相等,在這種情況下,原生的equals方法就不能滿足我們的需求了,所以這個(gè)時(shí)候我們需要重寫(xiě)equals方法

說(shuō)明:String為什么可以使用equals方法,只要字符串相等就為true,那是因?yàn)镾tring類重寫(xiě)了equals和hashCode方法,比較的是值

1、Person對(duì)象

public static void main(String[] args) {
        List<Person> personList = Lists.newArrayList();
        Person person1 = new Person("小小", 15);
        Person person2 = new Person("中中", 16);
        personList.add(person1);
        personList.add(person2);
        List<Person> person1List = Lists.newArrayList();
        Person person3 = new Person("中中", 16);
        Person person4 = new Person("大大", 17);
        person1List.add(person3);
        person1List.add(person4); 
        /** 1、差集 */ 
        System.out.println(CollectionUtils.subtract(personList,person1List)); //輸出:[Person{name='小小', age=15}]
        /** 2、交集 */ 
        System.out.println(CollectionUtils.intersection(personList,person1List)); //輸出:[Person{name='中中', age=16}]
         /** 3、并集 */ 
        System.out.println(CollectionUtils.union(personList,person1List)); //輸出:[Person{name='小小', age=15},                 Person{name='大大', age=17}, Person{name='中中', age=16}]
         /** 4、交集的補(bǔ)集(析?。?*/ 
        System.out.println(CollectionUtils.disjunction(personList,person1List)); //輸出:[Person{name='小小', age=15}, Person{name='大大', age=17}]
}

其他兩種方式就不測(cè)了,因?yàn)槎家粯?/p>

四、為什么要重寫(xiě)equals方法一定要重寫(xiě)hashCode方法 |

1、源碼

其實(shí)上面的Person類我可以只重寫(xiě)equals方法而不寫(xiě)hashCode方法,一樣能達(dá)到上面的效果,但為什么建議寫(xiě)上呢?官方說(shuō)法:對(duì)象的equals方法被重寫(xiě),那么對(duì)象的hashCode的也盡量重寫(xiě)

重寫(xiě)equals方法就必須重寫(xiě)hashCode的方法的原因,從源頭Object類講起就更好理解了

先來(lái)看Object關(guān)于hashCode()和equals()的源碼:

public native int hashCode(); 
public boolean equals(Object obj){ 
    return (this == obj);  
}

光從代碼中可以知道,hashCode方法是一個(gè)本地native方法,返回的是對(duì)象引用中存儲(chǔ)對(duì)象的內(nèi)存地址,而equals方法是利用==來(lái)比較也是對(duì)象的內(nèi)存地址,從上面看出,hashCode方法和equals方法是一致的,還有最關(guān)鍵的一點(diǎn)

我們來(lái)Object類中關(guān)于hashCode方法的注釋

1.在java應(yīng)用程序運(yùn)行期間,在對(duì)同一對(duì)象多次調(diào)用hashCode方法時(shí),必須一致地返回相同的整數(shù),前提是將對(duì)象進(jìn)行equals比較時(shí)所用的信息沒(méi)有被修改。

2.如果根據(jù)equals(Object)方法,兩個(gè)對(duì)象是相等的,那么對(duì)這兩個(gè)對(duì)象調(diào)用hashCode方法都必須生成相同的整數(shù)結(jié)果。

3.如果根據(jù)equals(java.lang.Object)方法,兩個(gè)對(duì)象不相等,那么對(duì)這兩個(gè)對(duì)象中的任一對(duì)象上調(diào)用hashCode方法不 要求一定生成不同的整數(shù)結(jié)果,但是,我們應(yīng)該意識(shí)到,為不相等的對(duì)象生成不同整數(shù)結(jié)果可以提高哈希表的性能

整理:hashCode和equals保持一致,如果equals方法返回true,那么兩個(gè)對(duì)象的hashCode返回值必須一樣,如果equals方法返回false,hashCode可以不一樣,但是這樣不利于哈希表的性能,一般我們也不要這樣做

假設(shè)兩個(gè)對(duì)象,重寫(xiě)了其equals方法,其相等條件是某屬性相等,就返回true,如果不重寫(xiě)hashCode方法,其返回的依然是兩個(gè)對(duì)象的內(nèi)存地址值,必然不相等,這就出現(xiàn)了equals方法相等,但是hashCode不相等的情況,這不符合hashCode的規(guī)則

2、HashSet和Map集合類型

重寫(xiě)equals方法就必須重寫(xiě)hashCode方法主要是針對(duì)HashSet和Map集合類型,而對(duì)于List集合到?jīng)]有什么影響

原因:在向HashSet集合中存入一個(gè)元素時(shí),HashSet會(huì)調(diào)用該對(duì)象(存入對(duì)象)的hashCode方法來(lái)得到該對(duì)象的hashCode值,然后根據(jù)該hashCode值決定該對(duì)象在HashSet中存儲(chǔ)的位置,簡(jiǎn)單的說(shuō):

HashSet集合判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是:兩個(gè)對(duì)象通過(guò)equals方法比較相等,并且兩個(gè)對(duì)象hashCode方法返回值也相等,如果兩個(gè)元素通過(guò)equals方法比較返回true,但是它們的hashCode方法返回值不同,HashSet會(huì)把它們存儲(chǔ)在不同的位置,依然可以添加成功

這就是問(wèn)題所在:就是如果你只重寫(xiě)equals方法,而不重寫(xiě)hashCode,如果equals為true,而它們的hashCode方法返回值肯定不一樣,因?yàn)樗鼈兌疾皇峭粚?duì)象所以內(nèi)存地址肯定不一樣,所以它還是添加成功了,那么其實(shí)你寫(xiě)的equals方法根本沒(méi)啥軟用

3、代碼示例

1、People類

重寫(xiě)equals方法,但并沒(méi)有hashCode方法

public class People { 
    private String name; 
    private Integer age; 
    public People(String name, Integer age) { 
        this.name = name;
        this.age = age;
    } 
   /** 重寫(xiě)equals方法
     * @param o
     * @return
     */ 
@Override 
public boolean equals(Object o) {
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false;
    People people = (People) o; 
    return Objects.equals(name, people.name) && Objects.equals(age, people.age);
} 
/** * 重寫(xiě)toString方法
     * @return
     */ 
@Override 
public String toString() { 
  return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

main:

public static void main(String[] args) {
        HashSet<People> hashSet = Sets.newHashSet();
        People people1 = new People("小小",3);
        People people2 = new People("中中",4);
        People people3 = new People("中中",4);
        People people4 = new People("大大",5);
        hashSet.add(people1);
        hashSet.add(people2);
        hashSet.add(people3);
        hashSet.add(people4);
        System.out.println(hashSet); 
      //輸出:[People{name='大大', age=5}, People{name='中中', age=4}, People{name='小小', age=3}, People{name='中中', age=4}]
}

很明顯,我重寫(xiě)equals方法,那么people2和people3的equals應(yīng)該相同,所以不能放入HashSet,但它們的hashCode方法返回不同,所以導(dǎo)致同樣能放入HashSet

重點(diǎn):對(duì)于Set集合必須要同時(shí)重寫(xiě)這兩個(gè)方法,要不然Set的特性就被破壞了

到此這篇關(guān)于Java的CollectionUtils工具類詳解的文章就介紹到這了,更多相關(guān)Java CollectionUtils內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java并發(fā)之串行線程池實(shí)例解析

    Java并發(fā)之串行線程池實(shí)例解析

    這篇文章主要介紹了Java并發(fā)之串行線程池實(shí)例解析,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • 深入理解Java中的注解Annotation

    深入理解Java中的注解Annotation

    這篇文章主要介紹了深入理解Java中的注解Annotation,注解在Java中確實(shí)也很常見(jiàn),但是人們常常不會(huì)自己定義一個(gè)注解拿來(lái)用,我們雖然很少去自定義注解,但是學(xué)會(huì)注解的寫(xiě)法,注解的定義,學(xué)會(huì)利用反射解析注解中的信息,在開(kāi)發(fā)中能夠使用到,這是很關(guān)鍵的,需要的朋友可以參考下
    2023-10-10
  • 圖文詳解java內(nèi)存回收機(jī)制

    圖文詳解java內(nèi)存回收機(jī)制

    這篇文章主要以圖文結(jié)合的方式為大家詳細(xì)介紹了java內(nèi)存回收機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • java反射應(yīng)用詳細(xì)介紹

    java反射應(yīng)用詳細(xì)介紹

    本篇文章依舊采用小例子來(lái)說(shuō)明java反射應(yīng)用,因?yàn)槲沂冀K覺(jué)的,案例驅(qū)動(dòng)是最好的,需要的朋友可以參考下
    2012-11-11
  • Java設(shè)計(jì)模式之裝飾器模式

    Java設(shè)計(jì)模式之裝飾器模式

    這篇文章介紹了Java設(shè)計(jì)模式之裝飾器模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • IDEA中創(chuàng)建properties配置文件

    IDEA中創(chuàng)建properties配置文件

    我們?cè)趈2ee當(dāng)中,連接數(shù)據(jù)庫(kù)的時(shí)候經(jīng)常會(huì)用到properties配置文件,本文主要介紹了IDEA中創(chuàng)建properties配置文件,具有一定的參考價(jià)值,?感興趣的可以了解一下
    2024-04-04
  • java使用JOptionPane猜數(shù)字游戲

    java使用JOptionPane猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了java使用JOptionPane猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫(kù)數(shù)據(jù)

    JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫(kù)數(shù)據(jù)

    MySQL是最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),在WEB應(yīng)用方面MySQL是最好的。本文將利用JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫(kù)數(shù)據(jù)功能,需要的可以參考一下
    2022-03-03
  • java使用CountDownLatch等待多線程全部執(zhí)行完成

    java使用CountDownLatch等待多線程全部執(zhí)行完成

    這篇文章主要為大家詳細(xì)介紹了使用CountDownLatch等待多線程全部執(zhí)行完成,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • 教你用Java在個(gè)人電腦上實(shí)現(xiàn)微信掃碼支付

    教你用Java在個(gè)人電腦上實(shí)現(xiàn)微信掃碼支付

    今天給大家?guī)?lái)的是Java實(shí)戰(zhàn)的相關(guān)知識(shí),文章圍繞著Java在個(gè)人電腦上實(shí)現(xiàn)微信掃碼支付展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06

最新評(píng)論

铁岭县| 丰顺县| 沈阳市| 海口市| 贵南县| 青州市| 错那县| 女性| 东丰县| 绥化市| 沂源县| 醴陵市| 香格里拉县| 德州市| 康乐县| 康马县| 麻城市| 巩义市| 杭锦旗| 宜良县| 恩平市| 通化市| 黑山县| 民乐县| 玛纳斯县| 满洲里市| 安阳市| 陵水| 都安| 潮州市| 涿鹿县| 灌阳县| 勃利县| 巴马| 兴化市| 顺义区| 芮城县| 潜江市| 临夏县| 阜阳市| 璧山县|