天天看點

Java中那些讓你愛不釋手工具庫,精煉代碼量Java中那些讓你愛不釋手工具庫,精煉代碼量

Java中那些讓你愛不釋手工具庫,精煉代碼量

一、JDK1.8 Stream新特性

1、Stream流的常見生成方式

①Collection體系的集合可以使用預設方法stream()生成流

//list轉stream流 
List<String> list = new ArrayList<>();        
Stream<String> listStream = list.stream();    
//Set轉stream流  
Set<String> set = new HashSet<>();        
Stream<String> setStream = set.stream();   
//map轉stream流
Map<String, Integer> map = new HashMap<>();      
Stream<String> keyStream = map.keySet().stream();      
Stream<Integer> valueStream = map.values().stream();    
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();  
           

②數組轉stream流

//第一種: 使用java.util.Arrays.stream(T[] array)方法用數組建立流      
int[] array={1,3,5,6,8};       
IntStream stream = Arrays.stream(array);   

//第二種: 可以通過Stream接口的靜态方法of(T... values)生成流      
String[] strArray = {"hello", "world", "java"};      
Stream<String> strArrayStream = Stream.of(strArray);     
Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");       Stream<Integer> intStream = Stream.of(10, 20, 30);
           

2、void forEach(Consumer<? super T> action)

Stream<String> stringStream = Stream.of("景天", "雪見", "長卿", "紫萱");        stringStream.forEach(System.out::println);        
 //列印結果: ["景天", "雪見", "長卿", "紫萱"]
           

3、Stream filter(Predicate predicate)

​ (說明: 用于對流中的資料進行過濾)

List<String> nameList = Arrays.asList("景天", "雪見", "長卿", "紫萱");
nameList.stream().filter(s -> s.startsWith("紫")).forEach(System.out::println);
//列印結果: 紫萱
           

4、Stream map(Function<? super T, ? extends R> mapper)

(說明: 可以将流中的元素映射到另一個流中)

List<Integer> num = Arrays.asList(1, 2, 3, 4, 5);   
 num.stream().map(n -> n * 2).forEach(System.out::println);     
//列印結果: [2, 4, 6, 8, 10]

           

5、Stream flatMap(Function function)

(說明:flatmap是stream的一種中間操作,對流進行 “扁平化” 處理,是它和stream的map一樣,是一種收集類型的stream中間操作,但是與map不同的是,它可以對stream流中單個元素再進行拆分(切片),從另一種角度上說,使用了它,就是使用了雙重for循環。)

// map 生成的是個 1:1 映射,每個輸入元素,都按照規則轉換成為另外一個元素。還有一些場景,是一對多映射關系的,這時需要 flatMap       
String[] strs = {"java8", "is", "easy", "to", "use"};     
List<String[]> distinctStrs = Arrays.stream(strs)
     .map(str -> str.split(""))    // 映射成為Stream<String[]>   
     .distinct().collect(Collectors.toList()); //distinct操作是以 “字元串數組“為單元進行去重        
/* 在執行map操作以後,我們得到是一個包含多個字元串數組的流,列印結果如下所示   
[j, a, v, a, 8]       
[i, s]      
[e, a, s, y]         
[t, o]         
[u, s, e]      
*/  

List<String> distinctStr = Arrays.stream(strs)
    .map(str -> str.split("")) // 映射成為Stream<String[]>       
    .flatMap(Arrays::stream)  // 扁平化為Stream<String>   
    .distinct().collect(Collectors.toList());      

/* flatMap将由map映射得到的Stream<String[]>,轉換成由各個字元串數組映射成的流Stream<String>,        再将這些小的流扁平化成為一個由所有字元串構成的大流Steam<String>,
   進而能夠達到我們的目的。            
   列印結果:            
   [j, a, v, 8, i, s, e, y, t, o, u]     
*/
           

6、Stream limit(long maxSize)

(說明: 傳回此流中的元素組成的流,截取前指定參數個數的資料)

List<String> limitList = Arrays.asList("景天", "雪見", "長卿", "紫萱");   
 //取前3個資料在控制台輸出      
 limitList.stream().limit(3).forEach(System.out::println);     
//列印結果:["景天", "雪見", "長卿"]
           

7、Stream skip(long n)

(說明: 跳過指定參數個數的資料,傳回由該流的剩餘元素組成的流)

//跳過3個元素,把剩下的元素在控制台輸出     
List<String> list = Arrays.asList("景天", "雪見", "長卿", "紫萱");   
list.stream().skip(3).forEach(System.out::println);    
//列印結果:["紫萱"]
           

8、static Stream concat(Stream a, Stream b)

(說明: 合并a和b兩個流為一個流)

List<String> concatList1 = Arrays.asList("景天", "雪見", "長卿", "紫萱");   
List<String> concatList2 = Arrays.asList("重樓", "茂茂", "必平", "龍葵");     
Stream<String> stream1 = concatList1.stream();   
Stream<String> stream2 = concatList2.stream();      
Stream.concat(stream1, stream2).forEach(System.out::println);   
// 列印結果: ["景天", "雪見", "長卿", "紫萱","重樓", "茂茂", "必平", "龍葵"]
           

9、Stream distinct()

(說明:對流中相同的元素進行去重處理)

List<String> distinctList = Arrays.asList("景天", "雪見", "長卿", "紫萱", "紫萱", "雪見"); distinctList.stream().distinct().forEach(System.out::println); 
// 列印結果: ["景天", "雪見", "長卿", "紫萱"]
           

10、Stream sorted()

(說明:傳回由此流的元素組成的流,根據自然順序排序)

//題目: 按照字母順序把資料在控制台輸出 sorted()是正序
List<String> sortList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent", "Charles","William");
sortList.stream().sorted().forEach(System.out::println);
//列印結果: [Anny,Charles,Jack,Lucy,Vincent,William] 
//題目: 按照名稱長度順序從短到長 把資料在控制台輸出 
sortList.stream().sorted(Comparator.comparingInt(String::length))
    .forEach(System.out::println); 
//列印結果:  [Lucy,Jack,Anny,Vincent,Charles,William]
           

11、Stream parallelStream()

(說明: 并行的操作,多線程執行,在大資料量下會優于 stream(), parallelStream()的底層思想是ForkJoinPool主要用來使用分治法(Divide-and-Conquer Algorithm)來解決問題)

List<String> stringList = new ArrayList<>();      
  for (int i = 0; i < 10; i++) {      
   stringList.add("第" + i + "條資料");       
  }        
 long parallelStreamNowTime = System.currentTimeMillis();  
 stringList.parallelStream().forEach(s -> {         
    try {               
        Thread.sleep(1000);      
    } catch (InterruptedException e) {         
        e.printStackTrace();          
    }     
});        
long parallelStreamTime = System.currentTimeMillis();      
System.out.println("Stream需要時間" + (parallelStreamTime - parallelStreamNowTime));        //列印結果:  Stream需要時間2027
           

​ PS:除了直接建立并行流,還可以通過parallel()把順序流轉換成并行流

12、count()

(說明: 傳回集合流中元素的個數)

List<String> countList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent","Charles", "William","William"); 
long count1 = countList.stream().count();
System.out.println("總元素個數是:"+count1);  // 列印結果 : 總元素個數是:7 

long count2 = countList.stream().distinct().count(); 
System.out.println("去重之後元素個數是:"+count2);  // 列印結果 : 去重之後元素個數是:6
           

13、boolean allMatch(Predicate predicate)

(說明:allMatch表示,判斷條件裡的元素,所有的元素都滿足條件,就傳回true)

List<Integer> integerList  = Arrays.asList(1,2,3,4,5);
 if(integerList.stream().allMatch(i->i>3)){
      System.out.println( "值都大于3");
  }
           

14、boolean anyMatch(Predicate predicate)

(說明: anyMatch表示,判斷的條件裡,任意一個元素符合條件,就傳回true)

List<Integer> integerList  = Arrays.asList(1,2,3,4,5); 
 if(integerList.stream().anyMatch(i->i>3)){
      System.out.println( "存在大于3的值");
  }
           

15、boolean noneMatch(Predicate predicate)

(說明: noneMatch跟allMatch相反,判斷條件裡的元素,所有的都不符合條件,才傳回true)

List<Integer> integerList  = Arrays.asList(1,2,3,4,5);  
if(integerList.stream().noneMatch(i -> i > 3)){
      System.out.println("值都小于3");
 }
           

14、A[] toArray(IntFunction<A[]> generator);

(說明: 使用提供的 generator函數傳回一個包含此流的元素的數組,以配置設定傳回的數組,以及分區執行或調整大小可能需要的任何其他數組。)

15、Stream concat(Stream a, b)

(說明:合并2個stream流)

List<String> strings = Arrays.asList("abc", "def", "gkh", "abc");
//concat 合并流
List<String> strings2 = Arrays.asList("xyz", "jqx");

List<String> concatList = Stream.concat(strings2.stream(),strings.stream())
    .collect(Collectors.toList());
System.out.println(concatList);  //列印結果: [xyz, jqx, abc, def, gkh, abc]
           

16、IntSummaryStatistics summaryStatistics()

(說明: 對stream流中的資料進行統計分析)

//對數組的統計,比如用
List<Integer> number = Arrays.asList(1, 2, 5, 4);
IntSummaryStatistics statistics = number.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("清單中最大的數 : "+statistics.getMax());
System.out.println("清單中最小的數 : "+statistics.getMin());
System.out.println("平均數 : "+statistics.getAverage());
System.out.println("所有數之和 : "+statistics.getSum());
           

17、Optional findAny()

(說明:findAny()操作,傳回的元素是不确定的,對于同一個清單多次調用findAny() 有可能會傳回不同的值。使用findAny()是為了更高效的性能。

①串行流情況下,一般會傳回符合條件的第一個結果;

List<String> list1 = Arrays.asList("A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3","C3"); 
 for(int i=0;i<10;i++) {   
  Optional<String> c = list1.stream().filter(s -> s.contains("A")).findAny(); 
  System.out.println("====串行流findAny()======" + c.get());  
} 
//列印結果:  
//  ====串行流findAny()======A1 
//  ====串行流findAny()======A1 
//  ====串行流findAny()======A1  
//  ====串行流findAny()======A1  
//  ====串行流findAny()======A1  
//  ====串行流findAny()======A1 
//  ====串行流findAny()======A1  
//  ====串行流findAny()======A1  
//  ====串行流findAny()======A1 
//  ====串行流findAny()======A1
           

②并行流的情況,在給定的元素中随機取一個元素,那就不能確定是第一個。)

List<String> list1 = Arrays.asList("A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3","C3"); Optional<String> a = list1.parallelStream().filter(s -> s.contains("A")).findAny(); System.out.println("====findAny()======" + a.get()); 

//列印結果:  每次執行列印的是A1或者A2或者A3中任意一個 
// ====并行流findAny()======A3
// ====并行流findAny()======A3 
// ====并行流findAny()======A2 
// ====并行流findAny()======A1 
// ====并行流findAny()======A1 
// ====并行流findAny()======A2 
// ====并行流findAny()======A3 
// ====并行流findAny()======A3 
// ====并行流findAny()======A3 
// ====并行流findAny()======A2
           

18、Optional findFirst()

(說明:傳回Stream中的第一個元素)

List<String> list2 = Arrays.asList("A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3","C3"); Optional<String> b = list2.parallelStream().filter(s -> s.contains("B")).findFirst(); System.out.println("====findFirst()====" + b.get());
// 列印結果:   ====findFirst()====B1
           

19、Optional max(Comparator comparator)

(說明:傳回比較器比較之後 結果最大的那個元素)

//擷取String集合中最長的元素。
List<String> maxList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent","Charles","William");
Optional<String> max = maxList.stream().
    max(Comparator.comparing(String::length));
System.out.println("最長的字元串:" + max.get());
//列印結果: 最長的字元串:Vincent
           

PS: Optional min(Comparator<? super T> comparator) 也是類似的,我就不多說了!

20、Optional reduce(BinaryOperator accumulator)

(說明: 根據指定的計算模型将Stream中的值計算得到一個最終結果)

List<Integer> reduceList = Arrays.asList(1, 3, 2, 8, 11, 4);
  // 求和方式1
 Optional<Integer> sum = reduceList.stream().reduce((x, y) -> x + y);
 // 求和方式2
 Optional<Integer> sum2 = reduceList.stream().reduce(Integer::sum);
 // 求和方式3
 Integer sum3 = reduceList.stream().reduce(0, Integer::sum);

  // 求乘積
  Optional<Integer> product = reduceList.stream().reduce((x, y) -> x * y);

  // 求最大值方式1
  Optional<Integer> max2 = reduceList.stream().reduce((x, y) -> x > y ? x : y);
  // 求最大值寫法2
  Integer max3 = reduceList.stream().reduce(1, Integer::max);

  System.out.println("list求和:" + sum.get() + "," + sum2.get() + "," + sum3);
  //列印結果:  list求和:29,29,29
  System.out.println("list求積:" + product.get());
  //列印結果:  list求積:2112
  System.out.println("list求最大值:" + max2.get() + "," + max3);
  //列印結果: list求最大值:11,11
           

二、List轉String

// 如何把list集合拼接成以逗号分隔的字元串 a,b,c
 List<String> list = Arrays.asList("a", "b", "c");

// 第一種方法,可以用stream流
 String join = list.stream().collect(Collectors.joining(","));
 System.out.println(join); // 輸出 a,b,c

 // 第二種方法,其實String也有join方法可以實作這個功能,合并數組為單一字元串,可傳分隔符
 String join1 = String.join(",", list);
 System.out.println(join1); // 輸出 a,b,c
           

三、玩轉StringUtils工具類

String str = "I love JavaAlliance forever";
// 1、删除字元串中指定字元,傳回一個string
String remove = StringUtils.remove(str, "forever"); // 移除字元串中的 forever
System.out.println(remove); // 列印結果是  I love JavaAlliance

// 2、将字元串反轉,傳回一個string
String reverse = StringUtils.reverse(str);
System.out.println(reverse); // 列印結果是  reverof ecnaillAavaJ evol I

// 3、比較兩個字元串是否相等,如果兩個均為null,則也認為相等
StringUtils.equals("Java", "Java"); // 結果是true
StringUtils.equals("", ""); // 結果是true
StringUtils.equals(null, null); // 結果是true
StringUtils.equals(null, ""); // 結果是false
StringUtils.equals("", null); // 結果是false
StringUtils.equals(null, ""); // 結果是false
StringUtils.equalsIgnoreCase("java", "JAVA"); // 不區分大小寫--結果是true

// 4、重複拼接字元串
String str1 = StringUtils.repeat("ab", 2);
System.out.println(str1); // 輸出abab

// 5、首字母轉成大寫
String str2 = "javaAlliance";
String capitalize = StringUtils.capitalize(str2);
System.out.println(capitalize); // 輸出JavaAlliance

// 6、字元串固定長度填充
StringUtils.leftPad("test", 8, "0"); // 字元串固定長度 8位,若不足,往左補 0
StringUtils.rightPad("test", 8, "0"); // 字元串固定長度 8位,若不足,往右補 0

// 7、字元串關鍵字替換
StringUtils.replace("aba", "a", "z")   = "zbz"; // 預設替換所有關鍵字
StringUtils.replaceOnce("aba", "a", "z")   = "zba";// 替換關鍵字,僅替換一次
StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "")   = "ABC123"; // 使用正規表達式替換

// 8、将數組拼接成字元串
StringUtils.join(["a", "b", "c"], ",") ; //拼接結果是  "a,b,c"

// 9、字元串拆分
StringUtils.split("a..b.c", '.')  //拆分結果是 ["a", "b", "c"]
StringUtils.splitByWholeSeparatorPreserveAllTokens("a..b.c", ".")  //拆分結果是 ["a","", "b", "c"]




           

四、玩轉BeanUtils工具類

User user = new User();
user.setUserName("JavaAlliance").setEmail("[email protected]");
// 對象轉map
Map<String, String> map = BeanUtils.describe(user);
System.out.println(map); // 輸出
// map轉對象
User newUser = new User();
BeanUtils.populate(newUser, map);
System.out.println(newUser); // 輸出
           

五、玩轉DateUtils/DateFormatUtils工具類

// Date類型轉String類型
String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println(date); // 輸出 2021-05-01 01:01:01

// String類型轉Date類型   該方法會将日期字元串按照第二參數中的String數組,依次比對,選擇合适的Pattern來解析。
Date date1 = DateUtils.parseDate("2021-05-01 01:01:01", new String[]{"yyyy-MM-dd HH:mm:ss"});

Date now = new Date();
// Date 加 1 天
Date addDays = DateUtils.addDays(now, 1);
// Date 加 33 分鐘
Date addMinutes = DateUtils.addMinutes(now, 33);
// Date 減去 233 秒
Date addSeconds = DateUtils.addSeconds(now, -233);
// 判斷是否 Wie 同一天
boolean sameDay = DateUtils.isSameDay(addDays, addMinutes);
// 過濾時分秒,若 now 為 2020-05-07 22:13:00 調用 truncate 方法以後
// 傳回時間為 2020-05-07 00:00:00
Date truncate = DateUtils.truncate(now, Calendar.DATE);

           

六、玩轉LocalDateTime工具類

Date now = new Date();
// Date轉成LocalDateTime 這裡指定使用目前系統預設時區
LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault())
    .toLocalDateTime();

// LocalDateTime轉成Date 這裡指定使用目前系統預設時區
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

// 按照 yyyy-MM-dd HH:mm:ss 轉化時間
LocalDateTime dateTime = LocalDateTime.parse("2020-05-07 22:34:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

// 将 LocalDateTime 格式化字元串
String format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(dateTime);

//LocalDateTime 擷取目前時間年份,月份
LocalDateTime now = LocalDateTime.now();
// 年
int year = now.getYear();
// 月
int month = now.getMonthValue();
// 日
int day = now.getDayOfMonth();

// LocalDateTime 進行日期加減,擷取下一天的時間
LocalDateTime now = LocalDateTime.now();
// 目前時間加一天
LocalDateTime plusDays = now.plusDays(1l);
// 目前時間減一個小時
LocalDateTime minusHours = now.minusHours(1l);
// 還有很多其他方法

           

七、玩轉CollectionUtils工具類

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、交集的補集(析取)disjunction
System.out.println(CollectionUtils.disjunction(listA, listB));
// 輸出:[1, 2, 5, 6]

// 4、差集(扣除)
System.out.println(CollectionUtils.subtract(listA, listB));
// 輸出:[1, 2]


  // 1、交集
 List<String> intersectionList = new ArrayList<>(listA);
 intersectionList.retainAll(listB);
 System.out.println(intersectionList);
 // 輸出:[3, 4]

 // 2、差集
 List<String> differenceList = new ArrayList<>(listA);
 differenceList.removeAll(listB);
 System.out.println(differenceList);
 // 輸出:[1, 2]

// 3、并集 (先做差集再做添加所有)
List<String> unionList = new ArrayList<>(listA);
unionList.removeAll(listB); // unionList [1, 2]
unionList.addAll(listB); // 添加[3,4,5,6]
System.out.println(unionList);
// 輸出:[1, 2, 3, 4, 5, 6]

           

注意 : 以上有2種取交集的方式即intersection和retainAll,我們這裡說下它們之間的差别 ,要注意的是它們的傳回類型是不一樣的,intersection傳回的是一個新的List集合,而retainAll傳回是Bollean類型那就說明retainAll方法是對原有集合進行處理再傳回原有集合,會改變原有集合中的内容。

思路點撥:

1、從性能角度來考慮的話,List自帶會高點,因為它不用再建立新的集合。

2、需要注意的是:因為retainAll因為會改變原有集合,是以該集合需要多次使用就不适合用retainAll。

注意: Arrays.asList将數組轉集合不能進行add和remove操作。因為調用Arrays.asList()生産的List的add、remove方法時報異常,這是由Arrays.asList() 傳回的市Arrays的内部類ArrayList, 而不是java.util.ArrayList。Arrays的内部類ArrayList和java.util.ArrayList都是繼承AbstractList,remove、add等方法AbstractList中是預設throw UnsupportedOperationException而且不作任何操作。java.util.ArrayList重新了這些方法而Arrays的内部類ArrayList沒有重新,是以會抛出異常。

八、玩轉 Guava工具包

1、Multiset

Multiset是什麼?顧名思義,Multiset和Set的差別就是可以儲存多個相同的對象。在JDK中,List和Set有一個基本的差別,就是List可以包含多個相同對象,且是有順序的,而Set不能有重複,且不保證順序(有些實作有順序,例如LinkedHashSet和SortedSet等)是以Multiset占據了List和Set之間的一個灰色地帶:允許重複,但是不保證順序。

常見使用場景:Multiset有一個有用的功能,就是跟蹤每種對象的數量,是以你可以用來進行數字統計。 常見的普通實作方式如下:

String str = "張三 李四 李四 王五 王五 王五";
 String[] strArr = str.split(" ");
 List<String> words = new ArrayList<>(Arrays.asList(strArr));
//建立一個HashMultiset集合,并将words集合資料放入
 Multiset<String> wordMultiset = HashMultiset.create();
 wordMultiset.addAll(words);
//将不同的元素放在一個集合set中
 for (String key : wordMultiset.elementSet()) {
   //檢視指定元素的個數
   System.out.println(key + "-->" + wordMultiset.count(key));
     //列印結果:  李四-->2    張三-->1   王五-->3
 }
           

2、Multimap

Multimap能夠實作一個鍵對應到多個值的效果

Multimap<String, String> myMultimap = ArrayListMultimap.create();
myMultimap.put("Fruits", "Bannana");
myMultimap.put("Fruits", "Apple");
myMultimap.put("Fruits", "Pear");
myMultimap.put("Fruits", "Pear");
myMultimap.put("Vegetables", "Carrot");

// 查詢Multimap中的存儲的元素個數
System.out.println(myMultimap.size()); // 列印結果: 5

//查詢鍵為“Fruits”所對應的value
Collection<String> fruits = myMultimap.get("Fruits");
System.out.println(fruits);//列印結果:  [Bannana, Apple, Pear, Pear]
Collection<String> vegetables = myMultimap.get("Vegetables");
System.out.println(vegetables); //列印結果: [Carrot]

// 循環疊代周遊整個 Multimap裡存儲的value值
for (String value : myMultimap.values()) {
    System.out.println(value);
      //列印結果:
      //Carrot
      //Bannana
      //Apple
      //Pear
      //Pear
 }

//移除其中一個元素
myMultimap.remove("Fruits", "Pear");
System.out.println(myMultimap.get("Fruits"));//列印結果: [Bannana, Apple, Pear]

//将鍵為"Fruits"所對應的value内容替換為集合  Arrays.asList("178","910","123")
//傳回的oldValues是之前的舊值
Collection<String> oldValues = myMultimap.replaceValues("Fruits", Arrays.asList("178","910","123"));

System.out.println("oldValues="+oldValues);//列印結果: oldValues=[Bannana, Apple, Pear]
System.out.println("myMultimap="+myMultimap);//列印結果: myMultimap={Vegetables=[Carrot], Fruits=[178, 910,123]}

//移除Multimap中鍵為“Fruits”的所有元素
myMultimap.removeAll("Fruits");
System.out.println(myMultimap.get("Fruits"));//列印結果: []
           

3、BiMap

BiMap

可以用來實作鍵值對的雙向映射需求,這樣我們就可以通過

Key

查找對對應的

Value

,也可以使用

Value

查找對應的

Key

。 Bimap要求key和value都唯一,如果key不唯一則覆寫key,如果value不唯一則直接報錯

//雙向map
BiMap<Integer,String> biMap=HashBiMap.create();
biMap.put(1,"張三");
biMap.put(2,"李四");
biMap.put(3,"王五");
biMap.put(4,"趙六");
biMap.put(5,"李七");
biMap.put(4,"小小");

//通過key值得到value值(注意key裡面的類型根據泛行
String value= biMap.get(1);
System.out.println("id為1的value值 --"+value); //列印結果: id為1的value值 --張三

//通過value值得到key值
int key= biMap.inverse().get("張三");
System.out.println("value為張三的key值 --"+key); //列印結果: value為張三的key值 --1

//通過key值重複,那麼vakue值會被覆寫。
String valuename= biMap.get(4);
System.out.println("id為4的value值 --"+valuename);//列印結果: id為4的value值 --小小
           

BiMap的常用實作有:

​ 1、HashBiMap: key 集合與 value 集合都有 HashMap 實作

​ 2、EnumBiMap: key 與 value 都必須是 enum 類型

​ 3、ImmutableBiMap: 不可修改的 BiMap

九、玩轉FileUtils-檔案操作工具類

檔案操作工具類提供一系列方法,可以讓我們快速讀取寫入檔案。

快速實作檔案/檔案夾拷貝操作 ,

FileUtils.copyDirectory/FileUtils.copyFile

1、擷取指定檔案夾上所有檔案

// 按照指定檔案字尾如java,txt等去查找指定檔案夾下的檔案
File directory = new File("E:\\test");
FileUtils.listFiles(directory, new String[]{"txt"}, false);
           

2、讀取該檔案所有行

// 讀取指定檔案所有行 不需要使用 while 循環讀取流了
List<String> lines = FileUtils.readLines(fileA)
           

3、寫檔案

// 1、 向一個檔案寫入一段文字
FileUtils.write(new File("D:/a/1.txt"), "檔案内容", "UTF-8", true);
	
// 2、以追加的方式寫入
FileUtils.writeStringToFile(new File("D:/a/1.txt"), "author:apple", "UTF-8", true);
	
//3、寫入多行
List<String> list= new ArrayList<String>();
list.add("第一行");
list.add("第二行");
FileUtils.writeLines(new File("D:/a/1.txt"), list, true);
           

4、讀檔案

//讀檔案  
System.out.println(FileUtils.readFileToString(new File("D:/a/1.txt"), "UTF-8"));

//傳回一個list 
System.out.println(FileUtils.readLines(new File("D:/a/1.txt"), "UTF-8")); 
           

5、删除檔案/檔案夾

// 删除檔案夾 
FileUtils.deleteDirectory(new File("D:/a"));  
	  
// 檔案夾不是空仍然可以被删除,永遠不會抛出異常  
FileUtils.deleteQuietly(new File("D:/a")); 
           

6、複制檔案

//結果是a和a1在同一目錄  
FileUtils.copyDirectory(new File("D:/a"), new File("D:/a1"));   

//結果是将a拷貝到a2下  
FileUtils.copyDirectoryToDirectory(new File("D:/a"), new File("D:/a2"));  
	  
//拷貝檔案  方式1 
FileUtils.copyFile(new File("d:/1.xml"), new File("d:/1.xml.bak"));  
//拷貝檔案  方式2
Writer write = new FileWriter("D:/abc_bak.txt");
InputStream ins = new FileInputStream(new File("D:/abc.txt"));
IOUtils.copy(ins, write);
write.close();
IOUtils.closeQuietly(ins);


//拷貝檔案到目錄中  
FileUtils.copyFileToDirectory(new File("d:/1.xml"), new File("d:/a"));  
	
//拷貝url到檔案  
FileUtils.copyURLToFile(new URL("http://www.a.com/1.xml"), new File("d:/1.xml"));
//可實作快速下載下傳
URL url = new URL("http://hzf-image-test.oss-cn-beijing.aliyuncs.com/hr_image/HF306268301810/1513632067664AbIB40pv_defalut.JPG?x-oss-process=image/resize,h_400");
File file = new File("/Users/jjs/Desktop/pic.jpg");
FileUtils.copyURLToFile(url, file);
           

7、移動檔案

//移動檔案 或 檔案夾  
//static void moveDirectory(File srcDir, File destDir)   
FileUtils.moveDirectory(new File("D:/a1"), new File("D:/a2")); //注意這裡 第二個參數檔案不存在會引發異常  
	
//static void moveDirectoryToDirectory(File src, File destDir, boolean createDestDir)   
FileUtils.moveDirectoryToDirectory(new File("D:/a2"), new File("D:/a3"), true);  
	
/* 上面兩個方法的不同是: 
 * moveDirectory:D:/a2裡的内容是D:/a1的内容。 
 * moveDirectoryToDirectory:D:/a2檔案夾移動到到D:/a3裡 
 */  
           

8、實作快速下載下傳檔案

//下載下傳方式1
URL url = new URL("http://www.baidu.com/img/baidu_logo.gif");
File file = new File("/Users/jjs/Desktop/baidu1.gif");
FileUtils.copyURLToFile(url, file);
	
//下載下傳方式2
InputStream in = new URL("http://www.baidu.com/img/baidu_logo.gif").openStream();
byte[] gif = IOUtils.toByteArray(in);
FileUtils.writeByteArrayToFile(new File("D:/baidu2.gif"), gif);
IOUtils.closeQuietly(in);

//下載下傳方式3
InputStream in3 = new URL("http://www.baidu.com/img/baidu_logo.gif").openStream();
byte[] gif3 = IOUtils.toByteArray(in3);
IOUtils.write(gif3, new FileOutputStream(new File("D:/baidu3.gif")));
IOUtils.closeQuietly(in3);
           

專注Java技術進階,系統設計,計算機網絡,資料結構算法,作業系統,設計模式,計算機組成原理等等更多精彩内容,盡情期待

Java中那些讓你愛不釋手工具庫,精煉代碼量Java中那些讓你愛不釋手工具庫,精煉代碼量