Java中那些讓你愛不釋手工具庫,精煉代碼量
一、JDK1.8 Stream新特性
1、Stream流的常見生成方式
①Collection體系的集合可以使用默認方法stream()生成流
//list轉(zhuǎn)stream流 List list = new ArrayList<>(); Stream listStream = list.stream(); //Set轉(zhuǎn)stream流 Set set = new HashSet<>(); Stream setStream = set.stream(); //map轉(zhuǎn)stream流Map map = new HashMap<>(); Stream keyStream = map.keySet().stream(); Stream valueStream = map.values().stream(); Stream> entryStream = map.entrySet().stream();
②數(shù)組轉(zhuǎn)stream流
//第一種: 使用java.util.Arrays.stream(T[] array)方法用數(shù)組創(chuàng)建流 int[] array={1,3,5,6,8}; IntStream stream = Arrays.stream(array); //第二種: 可以通過Stream接口的靜態(tài)方法of(T... values)生成流 String[] strArray = {"hello", "world", "java"}; Stream strArrayStream = Stream.of(strArray); Stream strArrayStream2 = Stream.of("hello", "world", "java"); Stream intStream = Stream.of(10, 20, 30);
2、void forEach(Consumer super T> action)
Stream stringStream = Stream.of("景天", "雪見", "長卿", "紫萱"); stringStream.forEach(System.out::println); //打印結(jié)果: ["景天", "雪見", "長卿", "紫萱"]
3、Stream filter(Predicate predicate)
? (說明: 用于對流中的數(shù)據(jù)進行過濾)
List nameList = Arrays.asList("景天", "雪見", "長卿", "紫萱");nameList.stream().filter(s -> s.startsWith("紫")).forEach(System.out::println);//打印結(jié)果: 紫萱
4、Stream map(Function super T, ? extends R> mapper)
(說明: 可以將流中的元素映射到另一個流中)
List num = Arrays.asList(1, 2, 3, 4, 5); num.stream().map(n -> n * 2).forEach(System.out::println); //打印結(jié)果: [2, 4, 6, 8, 10]
5、Stream flatMap(Function function)
(說明:flatmap是stream的一種中間操作,對流進行 “扁平化” 處理,是它和stream的map一樣,是一種收集類型的stream中間操作,但是與map不同的是,它可以對stream流中單個元素再進行拆分(切片),從另一種角度上說,使用了它,就是使用了雙重for循環(huán)。)
// map 生成的是個 1:1 映射,每個輸入元素,都按照規(guī)則轉(zhuǎn)換成為另外一個元素。還有一些場景,是一對多映射關(guān)系的,這時需要 flatMap String[] strs = {"java8", "is", "easy", "to", "use"}; List distinctStrs = Arrays.stream(strs) .map(str -> str.split("")) // 映射成為Stream .distinct().collect(Collectors.toList()); //distinct操作是以 “字符串數(shù)組“為單元進行去重 /* 在執(zhí)行map操作以后,我們得到是一個包含多個字符串數(shù)組的流,打印結(jié)果如下所示 [j, a, v, a, 8] [i, s] [e, a, s, y] [t, o] [u, s, e] */ List distinctStr = Arrays.stream(strs) .map(str -> str.split("")) // 映射成為Stream .flatMap(Arrays::stream) // 扁平化為Stream .distinct().collect(Collectors.toList()); /* flatMap將由map映射得到的Stream,轉(zhuǎn)換成由各個字符串數(shù)組映射成的流Stream, 再將這些小的流扁平化成為一個由所有字符串構(gòu)成的大流Steam, 從而能夠達到我們的目的。 打印結(jié)果: [j, a, v, 8, i, s, e, y, t, o, u] */
6、Stream limit(long maxSize)
(說明: 返回此流中的元素組成的流,截取前指定參數(shù)個數(shù)的數(shù)據(jù))
List limitList = Arrays.asList("景天", "雪見", "長卿", "紫萱"); //取前3個數(shù)據(jù)在控制臺輸出 limitList.stream().limit(3).forEach(System.out::println); //打印結(jié)果:["景天", "雪見", "長卿"]
7、Stream skip(long n)
(說明: 跳過指定參數(shù)個數(shù)的數(shù)據(jù),返回由該流的剩余元素組成的流)
//跳過3個元素,把剩下的元素在控制臺輸出 List list = Arrays.asList("景天", "雪見", "長卿", "紫萱"); list.stream().skip(3).forEach(System.out::println); //打印結(jié)果:["紫萱"]
8、static Stream concat(Stream a, Stream b)
(說明: 合并a和b兩個流為一個流)
List concatList1 = Arrays.asList("景天", "雪見", "長卿", "紫萱"); List concatList2 = Arrays.asList("重樓", "茂茂", "必平", "龍葵"); Stream stream1 = concatList1.stream(); Stream stream2 = concatList2.stream(); Stream.concat(stream1, stream2).forEach(System.out::println); // 打印結(jié)果: ["景天", "雪見", "長卿", "紫萱","重樓", "茂茂", "必平", "龍葵"]
9、Stream distinct()
(說明:對流中相同的元素進行去重處理)
List distinctList = Arrays.asList("景天", "雪見", "長卿", "紫萱", "紫萱", "雪見"); distinctList.stream().distinct().forEach(System.out::println); // 打印結(jié)果: ["景天", "雪見", "長卿", "紫萱"]
10、Stream sorted()
(說明:返回由此流的元素組成的流,根據(jù)自然順序排序)
//題目: 按照字母順序把數(shù)據(jù)在控制臺輸出 sorted()是正序List sortList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent", "Charles","William");sortList.stream().sorted().forEach(System.out::println);//打印結(jié)果: [Anny,Charles,Jack,Lucy,Vincent,William] //題目: 按照名稱長度順序從短到長 把數(shù)據(jù)在控制臺輸出 sortList.stream().sorted(Comparator.comparingInt(String::length)) .forEach(System.out::println); //打印結(jié)果: [Lucy,Jack,Anny,Vincent,Charles,William]
11、Stream parallelStream()
(說明: 并行的操作,多線程執(zhí)行,在大數(shù)據(jù)量下會優(yōu)于 stream(), parallelStream()的底層思想是ForkJoinPool主要用來使用分治法(Divide-and-Conquer Algorithm)來解決問題)
List stringList = new ArrayList<>(); for (int i = 0; i < 10; i++) { stringList.add("第" + i + "條數(shù)據(jù)"); } 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)); //打印結(jié)果: Stream需要時間2027
? PS:除了直接創(chuàng)建并行流,還可以通過parallel()把順序流轉(zhuǎn)換成并行流
Optional findFirst = list.stream().parallel().filter(x->x>6).findFirst();
12、count()
(說明: 返回集合流中元素的個數(shù))
List countList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent","Charles", "William","William"); long count1 = countList.stream().count();System.out.println("總元素個數(shù)是:"+count1); // 打印結(jié)果 : 總元素個數(shù)是:7 long count2 = countList.stream().distinct().count(); System.out.println("去重之后元素個數(shù)是:"+count2); // 打印結(jié)果 : 去重之后元素個數(shù)是:6
13、boolean allMatch(Predicate predicate)
(說明:allMatch表示,判斷條件里的元素,所有的元素都滿足條件,就返回true)
List 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 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 integerList = Arrays.asList(1,2,3,4,5); if(integerList.stream().noneMatch(i -> i > 3)){ System.out.println("值都小于3"); }
14、A[] toArray(IntFunction generator);
(說明: 使用提供的 generator函數(shù)返回一個包含此流的元素的數(shù)組,以分配返回的數(shù)組,以及分區(qū)執(zhí)行或調(diào)整大小可能需要的任何其他數(shù)組。)
15、Stream concat(Stream a, b)
(說明:合并2個stream流)
List strings = Arrays.asList("abc", "def", "gkh", "abc");//concat 合并流List strings2 = Arrays.asList("xyz", "jqx");List concatList = Stream.concat(strings2.stream(),strings.stream()) .collect(Collectors.toList());System.out.println(concatList); //打印結(jié)果: [xyz, jqx, abc, def, gkh, abc]
16、IntSummaryStatistics summaryStatistics()
(說明: 對stream流中的數(shù)據(jù)進行統(tǒng)計分析)
//對數(shù)組的統(tǒng)計,比如用List number = Arrays.asList(1, 2, 5, 4);IntSummaryStatistics statistics = number.stream().mapToInt((x) -> x).summaryStatistics();System.out.println("列表中最大的數(shù) : "+statistics.getMax());System.out.println("列表中最小的數(shù) : "+statistics.getMin());System.out.println("平均數(shù) : "+statistics.getAverage());System.out.println("所有數(shù)之和 : "+statistics.getSum());
17、Optional findAny()
(說明:findAny()操作,返回的元素是不確定的,對于同一個列表多次調(diào)用findAny() 有可能會返回不同的值。使用findAny()是為了更高效的性能。
①串行流情況下,一般會返回符合條件的第一個結(jié)果;
List list1 = Arrays.asList("A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3","C3"); for(int i=0;i<10;i++) { Optional c = list1.stream().filter(s -> s.contains("A")).findAny(); System.out.println("====串行流findAny()======" + c.get()); } //打印結(jié)果: // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1 // ====串行流findAny()======A1
②并行流的情況,在給定的元素中隨機取一個元素,那就不能確保是第一個。)
List list1 = Arrays.asList("A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3","C3"); Optional a = list1.parallelStream().filter(s -> s.contains("A")).findAny(); System.out.println("====findAny()======" + a.get()); //打印結(jié)果: 每次執(zhí)行打印的是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 list2 = Arrays.asList("A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3","C3"); Optional b = list2.parallelStream().filter(s -> s.contains("B")).findFirst(); System.out.println("====findFirst()====" + b.get());// 打印結(jié)果: ====findFirst()====B1
19、Optional max(Comparator comparator)
(說明:返回比較器比較之后 結(jié)果最大的那個元素)
//獲取String集合中最長的元素。List maxList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent","Charles","William");Optional max = maxList.stream(). max(Comparator.comparing(String::length));System.out.println("最長的字符串:" + max.get());//打印結(jié)果: 最長的字符串:Vincent
PS: Optional
20、Optional reduce(BinaryOperator accumulator)
(說明: 根據(jù)指定的計算模型將Stream中的值計算得到一個最終結(jié)果)
List reduceList = Arrays.asList(1, 3, 2, 8, 11, 4); // 求和方式1 Optional sum = reduceList.stream().reduce((x, y) -> x + y); // 求和方式2 Optional sum2 = reduceList.stream().reduce(Integer::sum); // 求和方式3 Integer sum3 = reduceList.stream().reduce(0, Integer::sum); // 求乘積 Optional product = reduceList.stream().reduce((x, y) -> x * y); // 求最大值方式1 Optional 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); //打印結(jié)果: list求和:29,29,29 System.out.println("list求積:" + product.get()); //打印結(jié)果: list求積:2112 System.out.println("list求最大值:" + max2.get() + "," + max3); //打印結(jié)果: list求最大值:11,11
二、List轉(zhuǎn)String
// 如何把list集合拼接成以逗號分隔的字符串 a,b,c List list = Arrays.asList("a", "b", "c");// 第一種方法,可以用stream流 String join = list.stream().collect(Collectors.joining(",")); System.out.println(join); // 輸出 a,b,c // 第二種方法,其實String也有join方法可以實現(xiàn)這個功能,合并數(shù)組為單一字符串,可傳分隔符 String join1 = String.join(",", list); System.out.println(join1); // 輸出 a,b,c
三、玩轉(zhuǎn)StringUtils工具類
String str = "I love JavaAlliance forever";// 1、刪除字符串中指定字符,返回一個stringString remove = StringUtils.remove(str, "forever"); // 移除字符串中的 foreverSystem.out.println(remove); // 打印結(jié)果是 I love JavaAlliance// 2、將字符串反轉(zhuǎn),返回一個stringString reverse = StringUtils.reverse(str);System.out.println(reverse); // 打印結(jié)果是 reverof ecnaillAavaJ evol I// 3、比較兩個字符串是否相等,如果兩個均為null,則也認為相等StringUtils.equals("Java", "Java"); // 結(jié)果是trueStringUtils.equals("", ""); // 結(jié)果是trueStringUtils.equals(null, null); // 結(jié)果是trueStringUtils.equals(null, ""); // 結(jié)果是falseStringUtils.equals("", null); // 結(jié)果是falseStringUtils.equals(null, ""); // 結(jié)果是falseStringUtils.equalsIgnoreCase("java", "JAVA"); // 不區(qū)分大小寫--結(jié)果是true// 4、重復拼接字符串String str1 = StringUtils.repeat("ab", 2);System.out.println(str1); // 輸出abab// 5、首字母轉(zhuǎn)成大寫String str2 = "javaAlliance";String capitalize = StringUtils.capitalize(str2);System.out.println(capitalize); // 輸出JavaAlliance// 6、字符串固定長度填充StringUtils.leftPad("test", 8, "0"); // 字符串固定長度 8位,若不足,往左補 0StringUtils.rightPad("test", 8, "0"); // 字符串固定長度 8位,若不足,往右補 0// 7、字符串關(guān)鍵字替換StringUtils.replace("aba", "a", "z") = "zbz"; // 默認替換所有關(guān)鍵字StringUtils.replaceOnce("aba", "a", "z") = "zba";// 替換關(guān)鍵字,僅替換一次StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "") = "ABC123"; // 使用正則表達式替換// 8、將數(shù)組拼接成字符串StringUtils.join(["a", "b", "c"], ",") ; //拼接結(jié)果是 "a,b,c"http:// 9、字符串拆分StringUtils.split("a..b.c", .) //拆分結(jié)果是 ["a", "b", "c"]StringUtils.splitByWholeSeparatorPreserveAllTokens("a..b.c", ".") //拆分結(jié)果是 ["a","", "b", "c"]
四、玩轉(zhuǎn)BeanUtils工具類
User user = new User();user.setUserName("JavaAlliance").setEmail("196432@qq.com");// 對象轉(zhuǎn)mapMap map = BeanUtils.describe(user);System.out.println(map); // 輸出// map轉(zhuǎn)對象User newUser = new User();BeanUtils.populate(newUser, map);System.out.println(newUser); // 輸出
五、玩轉(zhuǎn)DateUtils/DateFormatUtils工具類
// Date類型轉(zhuǎn)String類型String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");System.out.println(date); // 輸出 2021-05-01 01:01:01// String類型轉(zhuǎn)Date類型 該方法會將日期字符串按照第二參數(shù)中的String數(shù)組,依次比對,選擇合適的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 調(diào)用 truncate 方法以后// 返回時間為 2020-05-07 00:00:00Date truncate = DateUtils.truncate(now, Calendar.DATE);
六、玩轉(zhuǎn)LocalDateTime工具類
Date now = new Date();// Date轉(zhuǎn)成LocalDateTime 這里指定使用當前系統(tǒng)默認時區(qū)LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime();// LocalDateTime轉(zhuǎn)成Date 這里指定使用當前系統(tǒng)默認時區(qū)Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());// 按照 yyyy-MM-dd HH:mm:ss 轉(zhuǎn)化時間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);// 還有很多其他方法
七、玩轉(zhuǎn)CollectionUtils工具類
String[] arrayA = new String[]{"1", "2", "3", "4"};String[] arrayB = new String[]{"3", "4", "5", "6"};List listA = Arrays.asList(arrayA);List listB = Arrays.asList(arrayB);// 1、并集 unionSystem.out.println(CollectionUtils.union(listA, listB));// 輸出: [1, 2, 3, 4, 5, 6]// 2、交集 intersectionSystem.out.println(CollectionUtils.intersection(listA, listB));// 輸出:[3, 4]// 3、交集的補集(析取)disjunctionSystem.out.println(CollectionUtils.disjunction(listA, listB));// 輸出:[1, 2, 5, 6]// 4、差集(扣除)System.out.println(CollectionUtils.subtract(listA, listB));// 輸出:[1, 2] // 1、交集 List intersectionList = new ArrayList<>(listA); intersectionList.retainAll(listB); System.out.println(intersectionList); // 輸出:[3, 4] // 2、差集 List differenceList = new ArrayList<>(listA); differenceList.removeAll(listB); System.out.println(differenceList); // 輸出:[1, 2]// 3、并集 (先做差集再做添加所有)List 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方法是對原有集合進行處理再返回原有集合,會改變原有集合中的內(nèi)容。
思路點撥:
1、從性能角度來考慮的話,List自帶會高點,因為它不用再創(chuàng)建新的集合。
2、需要注意的是:因為retainAll因為會改變原有集合,所以該集合需要多次使用就不適合用retainAll。
注意: Arrays.asList將數(shù)組轉(zhuǎn)集合不能進行add和remove操作。因為調(diào)用Arrays.asList()生產(chǎn)的List的add、remove方法時報異常,這是由Arrays.asList() 返回的市Arrays的內(nèi)部類ArrayList, 而不是java.util.ArrayList。Arrays的內(nèi)部類ArrayList和java.util.ArrayList都是繼承AbstractList,remove、add等方法AbstractList中是默認throw UnsupportedOperationException而且不作任何操作。java.util.ArrayList重新了這些方法而Arrays的內(nèi)部類ArrayList沒有重新,所以會拋出異常。
八、玩轉(zhuǎn) Guava工具包
1、Multiset
Multiset是什么?顧名思義,Multiset和Set的區(qū)別就是可以保存多個相同的對象。在JDK中,List和Set有一個基本的區(qū)別,就是List可以包含多個相同對象,且是有順序的,而Set不能有重復,且不保證順序(有些實現(xiàn)有順序,例如LinkedHashSet和SortedSet等)所以Multiset占據(jù)了List和Set之間的一個灰色地帶:允許重復,但是不保證順序。
常見使用場景:Multiset有一個有用的功能,就是跟蹤每種對象的數(shù)量,所以你可以用來進行數(shù)字統(tǒng)計。 常見的普通實現(xiàn)方式如下:
String str = "張三 李四 李四 王五 王五 王五"; String[] strArr = str.split(" "); List words = new ArrayList<>(Arrays.asList(strArr));//創(chuàng)建一個HashMultiset集合,并將words集合數(shù)據(jù)放入 Multiset wordMultiset = HashMultiset.create(); wordMultiset.addAll(words);//將不同的元素放在一個集合set中 for (String key : wordMultiset.elementSet()) { //查看指定元素的個數(shù) System.out.println(key + "-->" + wordMultiset.count(key)); //打印結(jié)果: 李四-->2 張三-->1 王五-->3 }
2、Multimap
Multimap能夠?qū)崿F(xiàn)一個鍵對應到多個值的效果
Multimap myMultimap = ArrayListMultimap.create();myMultimap.put("Fruits", "Bannana");myMultimap.put("Fruits", "Apple");myMultimap.put("Fruits", "Pear");myMultimap.put("Fruits", "Pear");myMultimap.put("Vegetables", "Carrot");// 查詢Multimap中的存儲的元素個數(shù)System.out.println(myMultimap.size()); // 打印結(jié)果: 5//查詢鍵為“Fruits”所對應的valueCollection fruits = myMultimap.get("Fruits");System.out.println(fruits);//打印結(jié)果: [Bannana, Apple, Pear, Pear]Collection vegetables = myMultimap.get("Vegetables");System.out.println(vegetables); //打印結(jié)果: [Carrot]// 循環(huán)迭代遍歷整個 Multimap里存儲的value值for (String value : myMultimap.values()) { System.out.println(value); //打印結(jié)果: //Carrot //Bannana //Apple //Pear //Pear }//移除其中一個元素myMultimap.remove("Fruits", "Pear");System.out.println(myMultimap.get("Fruits"));//打印結(jié)果: [Bannana, Apple, Pear]//將鍵為"Fruits"所對應的value內(nèi)容替換為集合 Arrays.asList("178","910","123")//返回的oldValues是之前的舊值Collection oldValues = myMultimap.replaceValues("Fruits", Arrays.asList("178","910","123"));System.out.println("oldValues="+oldValues);//打印結(jié)果: oldValues=[Bannana, Apple, Pear]System.out.println("myMultimap="+myMultimap);//打印結(jié)果: myMultimap={Vegetables=[Carrot], Fruits=[178, 910,123]}//移除Multimap中鍵為“Fruits”的所有元素myMultimap.removeAll("Fruits");System.out.println(myMultimap.get("Fruits"));//打印結(jié)果: []
3、BiMap
BiMap
可以用來實現(xiàn)鍵值對的雙向映射需求,這樣我們就可以通過 Key
查找對對應的 Value
,也可以使用 Value
查找對應的 Key
。 Bimap要求key和value都唯一,如果key不唯一則覆蓋key,如果value不唯一則直接報錯
//雙向mapBiMap biMap=HashBiMap.create();biMap.put(1,"張三");biMap.put(2,"李四");biMap.put(3,"王五");biMap.put(4,"趙六");biMap.put(5,"李七");biMap.put(4,"小小");//通過key值得到value值(注意key里面的類型根據(jù)泛行String value= biMap.get(1);System.out.println("id為1的value值 --"+value); //打印結(jié)果: id為1的value值 --張三//通過value值得到key值int key= biMap.inverse().get("張三");System.out.println("value為張三的key值 --"+key); //打印結(jié)果: value為張三的key值 --1//通過key值重復,那么vakue值會被覆蓋。String valuename= biMap.get(4);System.out.println("id為4的value值 --"+valuename);//打印結(jié)果: id為4的value值 --小小
BiMap的常用實現(xiàn)有:
? 1、HashBiMap: key 集合與 value 集合都有 HashMap 實現(xiàn)
? 2、EnumBiMap: key 與 value 都必須是 enum 類型
? 3、ImmutableBiMap: 不可修改的 BiMap
九、玩轉(zhuǎn)FileUtils-文件操作工具類
文件操作工具類提供一系列方法,可以讓我們快速讀取寫入文件。
快速實現(xiàn)文件/文件夾拷貝操作 ,FileUtils.copyDirectory/FileUtils.copyFile
1、獲取指定文件夾上所有文件
// 按照指定文件后綴如java,txt等去查找指定文件夾下的文件File directory = new File("E://test");FileUtils.listFiles(directory, new String[]{"txt"}, false);
2、讀取該文件所有行
// 讀取指定文件所有行 不需要使用 while 循環(huán)讀取流了List lines = FileUtils.readLines(fileA)
3、寫文件
// 1、 向一個文件寫入一段文字FileUtils.write(new File("D:/a/1.txt"), "文件內(nèi)容", "UTF-8", true);// 2、以追加的方式寫入FileUtils.writeStringToFile(new File("D:/a/1.txt"), "author:apple", "UTF-8", true);//3、寫入多行List list= new ArrayList();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、復制文件
//結(jié)果是a和a1在同一目錄 FileUtils.copyDirectory(new File("D:/a"), new File("D:/a1")); //結(jié)果是將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")); //拷貝文件 方式2Writer 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"));//可實現(xiàn)快速下載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")); //注意這里 第二個參數(shù)文件不存在會引發(fā)異常 //static void moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) FileUtils.moveDirectoryToDirectory(new File("D:/a2"), new File("D:/a3"), true); /* 上面兩個方法的不同是: * moveDirectory:D:/a2里的內(nèi)容是D:/a1的內(nèi)容。 * moveDirectoryToDirectory:D:/a2文件夾移動到到D:/a3里 */
8、實現(xiàn)快速下載文件
//下載方式1URL url = new URL("http://www.baidu.com/img/baidu_logo.gif");File file = new File("/Users/jjs/Desktop/baidu1.gif");FileUtils.copyURLToFile(url, file);//下載方式2InputStream 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);//下載方式3InputStream 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技術(shù)進階,系統(tǒng)設(shè)計,計算機網(wǎng)絡(luò),數(shù)據(jù)結(jié)構(gòu)算法,操作系統(tǒng),設(shè)計模式,計算機組成原理等等更多精彩內(nèi)容,盡情期待