Java中那些让你爱不释手工具库,精炼代码量
一、JDK1.8 Stream新特性
1、Stream流的常见生成方式
①Collection体系的集合可以使用默认方法stream()生成流
List<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<>();
Stream<String> setStream = set.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流
int[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);
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);
5、Stream flatMap(Function function)
(说明:flatmap是stream的一种中间操作,对流进行 “扁平化” 处理,是它和stream的map一样,是一种收集类型的stream中间操作,但是与map不同的是,它可以对stream流中单个元素再进行拆分(切片),从另一种角度上说,使用了它,就是使用了双重for循环。)
String[] strs = {"java8", "is", "easy", "to", "use"};
List<String[]> distinctStrs = Arrays.stream(strs)
.map(str -> str.split(""))
.distinct().collect(Collectors.toList());
List<String> distinctStr = Arrays.stream(strs)
.map(str -> str.split(""))
.flatMap(Arrays::stream)
.distinct().collect(Collectors.toList());
6、Stream limit(long maxSize)
(说明: 返回此流中的元素组成的流,截取前指定参数个数的数据)
List<String> limitList = Arrays.asList("景天", "雪见", "长卿", "紫萱");
limitList.stream().limit(3).forEach(System.out::println);
7、Stream skip(long n)
(说明: 跳过指定参数个数的数据,返回由该流的剩余元素组成的流)
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()
(说明:返回由此流的元素组成的流,根据自然顺序排序)
List<String> sortList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent", "Charles","William");
sortList.stream().sorted().forEach(System.out::println);
sortList.stream().sorted(Comparator.comparingInt(String::length))
.forEach(System.out::println);
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));
? PS:除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流
Optional<Integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();
12、count()
(说明: 返回集合流中元素的个数)
List<String> countList = Arrays.asList("Lucy", "Jack", "Anny", "Vincent","Charles", "William","William");
long count1 = countList.stream().count();
System.out.println("总元素个数是:"+count1);
long count2 = countList.stream().distinct().count();
System.out.println("去重之后元素个数是:"+count2);
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");
List<String> strings2 = Arrays.asList("xyz", "jqx");
List<String> concatList = Stream.concat(strings2.stream(),strings.stream())
.collect(Collectors.toList());
System.out.println(concatList);
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());
}
②并行流的情况,在给定的元素中随机取一个元素,那就不能确保是第一个。)
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());
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());
19、Optional max(Comparator comparator)
(说明:返回比较器比较之后 结果最大的那个元素)
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());
PS: Optional min(Comparator<? super T> comparator) 也是类似的,我就不多说了!
20、Optional reduce(BinaryOperator accumulator)
(说明: 根据指定的计算模型将Stream中的值计算得到一个最终结果)
List<Integer> reduceList = Arrays.asList(1, 3, 2, 8, 11, 4);
Optional<Integer> sum = reduceList.stream().reduce((x, y) -> x + y);
Optional<Integer> sum2 = reduceList.stream().reduce(Integer::sum);
Integer sum3 = reduceList.stream().reduce(0, Integer::sum);
Optional<Integer> product = reduceList.stream().reduce((x, y) -> x * y);
Optional<Integer> max2 = reduceList.stream().reduce((x, y) -> x > y ? x : y);
Integer max3 = reduceList.stream().reduce(1, Integer::max);
System.out.println("list求和:" + sum.get() + "," + sum2.get() + "," + sum3);
System.out.println("list求积:" + product.get());
System.out.println("list求最大值:" + max2.get() + "," + max3);
二、List转String
List<String> list = Arrays.asList("a", "b", "c");
String join = list.stream().collect(Collectors.joining(","));
System.out.println(join);
String join1 = String.join(",", list);
System.out.println(join1);
三、玩转StringUtils工具类
String str = "I love JavaAlliance forever";
String remove = StringUtils.remove(str, "forever");
System.out.println(remove);
String reverse = StringUtils.reverse(str);
System.out.println(reverse);
StringUtils.equals("Java", "Java");
StringUtils.equals("", "");
StringUtils.equals(null, null);
StringUtils.equals(null, "");
StringUtils.equals("", null);
StringUtils.equals(null, "");
StringUtils.equalsIgnoreCase("java", "JAVA");
String str1 = StringUtils.repeat("ab", 2);
System.out.println(str1);
String str2 = "javaAlliance";
String capitalize = StringUtils.capitalize(str2);
System.out.println(capitalize);
StringUtils.leftPad("test", 8, "0");
StringUtils.rightPad("test", 8, "0");
StringUtils.replace("aba", "a", "z") = "zbz";
StringUtils.replaceOnce("aba", "a", "z") = "zba";
StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "") = "ABC123";
StringUtils.join(["a", "b", "c"], ",") ;
StringUtils.split("a..b.c", '.')
StringUtils.splitByWholeSeparatorPreserveAllTokens("a..b.c", ".")
四、玩转BeanUtils工具类
User user = new User();
user.setUserName("JavaAlliance").setEmail("196432@qq.com");
Map<String, String> map = BeanUtils.describe(user);
System.out.println(map);
User newUser = new User();
BeanUtils.populate(newUser, map);
System.out.println(newUser);
五、玩转DateUtils/DateFormatUtils工具类
String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println(date);
Date date1 = DateUtils.parseDate("2021-05-01 01:01:01", new String[]{"yyyy-MM-dd HH:mm:ss"});
Date now = new Date();
Date addDays = DateUtils.addDays(now, 1);
Date addMinutes = DateUtils.addMinutes(now, 33);
Date addSeconds = DateUtils.addSeconds(now, -233);
boolean sameDay = DateUtils.isSameDay(addDays, addMinutes);
Date truncate = DateUtils.truncate(now, Calendar.DATE);
六、玩转LocalDateTime工具类
Date now = new Date();
LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault())
.toLocalDateTime();
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime dateTime = LocalDateTime.parse("2020-05-07 22:34:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(dateTime);
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
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);
System.out.println(CollectionUtils.union(listA, listB));
System.out.println(CollectionUtils.intersection(listA, listB));
System.out.println(CollectionUtils.disjunction(listA, listB));
System.out.println(CollectionUtils.subtract(listA, listB));
List<String> intersectionList = new ArrayList<>(listA);
intersectionList.retainAll(listB);
System.out.println(intersectionList);
List<String> differenceList = new ArrayList<>(listA);
differenceList.removeAll(listB);
System.out.println(differenceList);
List<String> unionList = new ArrayList<>(listA);
unionList.removeAll(listB);
unionList.addAll(listB);
System.out.println(unionList);
注意 : 以上有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));
Multiset<String> wordMultiset = HashMultiset.create();
wordMultiset.addAll(words);
for (String key : wordMultiset.elementSet()) {
System.out.println(key + "-->" + wordMultiset.count(key));
}
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");
System.out.println(myMultimap.size());
Collection<String> fruits = myMultimap.get("Fruits");
System.out.println(fruits);
Collection<String> vegetables = myMultimap.get("Vegetables");
System.out.println(vegetables);
for (String value : myMultimap.values()) {
System.out.println(value);
}
myMultimap.remove("Fruits", "Pear");
System.out.println(myMultimap.get("Fruits"));
Collection<String> oldValues = myMultimap.replaceValues("Fruits", Arrays.asList("178","910","123"));
System.out.println("oldValues="+oldValues);
System.out.println("myMultimap="+myMultimap);
myMultimap.removeAll("Fruits");
System.out.println(myMultimap.get("Fruits"));
3、BiMap
BiMap 可以用来实现键值对的双向映射需求,这样我们就可以通过 Key 查找对对应的 Value ,也可以使用 Value 查找对应的 Key 。 Bimap要求key和value都唯一,如果key不唯一则覆盖key,如果value不唯一则直接报错
BiMap<Integer,String> biMap=HashBiMap.create();
biMap.put(1,"张三");
biMap.put(2,"李四");
biMap.put(3,"王五");
biMap.put(4,"赵六");
biMap.put(5,"李七");
biMap.put(4,"小小");
String value= biMap.get(1);
System.out.println("id为1的value值 --"+value);
int key= biMap.inverse().get("张三");
System.out.println("value为张三的key值 --"+key);
String valuename= biMap.get(4);
System.out.println("id为4的value值 --"+valuename);
BiMap的常用实现有:
? 1、HashBiMap: key 集合与 value 集合都有 HashMap 实现
? 2、EnumBiMap: key 与 value 都必须是 enum 类型
? 3、ImmutableBiMap: 不可修改的 BiMap
九、玩转FileUtils-文件操作工具类
文件操作工具类提供一系列方法,可以让我们快速读取写入文件。
快速实现文件/文件夹拷贝操作 ,FileUtils.copyDirectory/FileUtils.copyFile
1、获取指定文件夹上所有文件
File directory = new File("E:\\test");
FileUtils.listFiles(directory, new String[]{"txt"}, false);
2、读取该文件所有行
List<String> lines = FileUtils.readLines(fileA)
3、写文件
FileUtils.write(new File("D:/a/1.txt"), "文件内容", "UTF-8", true);
FileUtils.writeStringToFile(new File("D:/a/1.txt"), "author:apple", "UTF-8", true);
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"));
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、复制文件
FileUtils.copyDirectory(new File("D:/a"), new File("D:/a1"));
FileUtils.copyDirectoryToDirectory(new File("D:/a"), new File("D:/a2"));
FileUtils.copyFile(new File("d:/1.xml"), new File("d:/1.xml.bak"));
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"));
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、移动文件
FileUtils.moveDirectory(new File("D:/a1"), new File("D:/a2"));
FileUtils.moveDirectoryToDirectory(new File("D:/a2"), new File("D:/a3"), true);
8、实现快速下载文件
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);
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);
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技术进阶,系统设计,计算机网络,数据结构算法,操作系统,设计模式,计算机组成原理等等更多精彩内容,尽情期待
|