public void test() {
Map<String, Integer> map = ImmutableMap.of("wxx", 18, "mjp", 20);
String res = Joiner.on(",").withKeyValueSeparator("-").join(map);
System.out.println(res);//"wxx-18,mjp-20"
}
public void test() {
List<Integer> list = Lists.newArrayList(1, 2, 3, null);
String res = Joiner.on("#").skipNulls().join(list);
System.out.println(res);//1#2#3
}
public void test2() {
List<Integer> list = Lists.newArrayList(1, 2, 3, null);
String res = Joiner.on("#").useForNull("0").join(list);
System.out.println(res);//1#2#3#0,将null替换为0
}
public void test3() {
List<Integer> list = Lists.newArrayList(1, 2, 3, null);
try (FileWriter fileWriter = new FileWriter(new File("D:\\新建文件夹\\log.txt"))){
FileWriter res = Joiner.on("#").useForNull("0").appendTo(fileWriter, list);
} catch (IOException e) {
}
}
public void test() {
List<String> res = Splitter.fixedLength(4).
omitEmptyStrings().limit(3).splitToList("2023051411:59:59");
System.out.println(res);//[2023, 0514, 11:59]
}
public void test1() {
List<String> list = Splitter.on("-").omitEmptyStrings()
.splitToList("2023-0511-11:59:53");
System.out.println(list);
}
public void test2() {
Map<String, String> res = Splitter.on(Pattern.compile("\\,")).omitEmptyStrings()
.withKeyValueSeparator(":").split("wxx:18,mjp:20");
System.out.println(res);//{wxx=18, mjp=20}
}
@Test(expected = IllegalArgumentException.class)
public void test1() {
User wxx = null;
Preconditions.checkArgument(Objects.nonNull(wxx), "用户不能为空");
}
建议使用StringUtils
public void test1() {
String s = Strings.commonPrefix("java", "jar");
System.out.println(s);//ja
}
public void test() {
String s = Strings.padStart("32", 4, '0');//StringUtils.leftPad("1", 2, '0');
System.out.println(s);//0032
}
public void test2() {
boolean numeric = StringUtils.isNumeric("520w");
System.out.println(numeric);//false
}
public void test2() {
boolean b = StringUtils.containsOnly("hlo", "hello");
System.out.println(b);//true
}
同理s1 和 s2是否有交集—
boolean alpha = StringUtils.isAlpha("qq.com");
System.out.println(alpha);//false
public void test2() {
String s ="2023-0514-11:59:59";
String res = StringUtils.substringBefore(s, "-");
System.out.println(res);//2023
String res1 = StringUtils.substringBeforeLast(s, "-");
System.out.println(res1);//2023-0514
}
public void test2() {
String res = StringUtils.abbreviate("Hello Java","-", 3);//前2个字符正常取,>=3后面的元素使用-代替
System.out.println(res);//He-
}
public void test2() {
String res = StringUtils.abbreviate("Hello Java","", 3);//取前3个字符串
System.out.println(res);//Hel
}
String s = StringUtils.left("hello java", 3);
System.out.println(s);//hel
String s = StringUtils.truncate("hello java", 0, 5);
System.out.println(s);//hello
String s = StringUtils.mid("2023-0514-11:59:59", 5, 4);
System.out.println(s);//0514
public void test2() {
String strip = StringUtils.strip(" java ");
System.out.println(strip);//java
}
String s = " i love java ";
String strip = StringUtils.strip(s);
String trim = StringUtils.trim(s);
String deleteWhitespace = StringUtils.deleteWhitespace(s);
System.out.println(strip);//i love java
System.out.println(trim);//i love java
System.out.println(deleteWhitespace);//ilovejava
public void test2() {
String s = "java";
String res = StringUtils.capitalize(s);
System.out.println(res);//Java
}
int[] att = StringUtils.toCodePoints("aA你");
System.out.println(Arrays.toString(att));//[97, 65, 20320]
public void test2() {
int nCount = StringUtils.countMatches(
"UPDATE tb_table SET x =? , y=?, z=? WHERE id=?", "?");
System.out.println(nCount);//4
}
String s = " hello world i love java ! ";
String[] strings = StringUtils.split(s.trim(), " ");
CollectionUtils.reverseArray(strings);
String res = StringUtils.join(strings, " ");
System.out.println(res);//! java love i world hello
给字符串"1"左侧填充0,填充后字符串长度为2,即"01"
String res = StringUtils.leftPad("1", 2, '0');//01
String s = StringUtils.prependIfMissing("www.baidu.com", "https://");
System.out.println(s);//https://www.baidu.com
StringUtils.difference("abc456","abc123");//s2独有的内容:123
String s = StringUtils.getCommonPrefix("abc456","ab123", "accc");
System.out.println(s);//a
String s = StringUtils.getDigits("[email protected]");
System.out.println(s);//15162265411
public void test1() {
String s =
CharMatcher.inRange('0', '9').or(CharMatcher.whitespace()).removeFrom("15162 265421@qq. com");
System.out.println(s);//@qq.com
String s1 =
CharMatcher.inRange('0', '9').or(CharMatcher.whitespace()).retainFrom("15162 265421@qq. com");
System.out.println(s1);//15162 265421
}
public void test1() {
boolean matches = CharMatcher.inRange('0', '9').or(CharMatcher.whitespace()).matches('.');
System.out.println(matches);//false
}
StringUtils中的isAlpha入参为CharSequence,而matches入参为char
boolean result = CharMatcher.whitespace().matchesAnyOf("111 12222");
System.out.println(result);//true
public void test1() {
String res = CharMatcher.inRange('0', '9').or(CharMatcher.whitespace())
.replaceFrom("i love java 1314", "-");
System.out.println(res);//i-love-java-----
}
String s = CharMatcher.whitespace().collapseFrom(" i love java", '-');
System.out.println(s);//-i-love-java
public void test1() {
String str3 = " ab\tcd\nef\bg";
String res = CharMatcher.javaIsoControl().removeFrom(str3);
System.out.println(res);//abcdefg
}
int n = CharMatcher.inRange('0', '9').countIn("[email protected]");
System.out.println(n);//14
String s1 = CharMatcher.whitespace().trimAndCollapseFrom(" i love java ", '-');
System.out.println(s1);//i-love-java
public void test1() throws InterruptedException {
Stopwatch stopwatch = Stopwatch.createStarted();
func1();
System.out.println(stopwatch.stop());//999.7 ms
}
private void func1() throws InterruptedException {
TimeUnit.SECONDS.sleep(1L);
}
项目实战已使用
public void test() throws InterruptedException {
StopWatch stopWatch = new StopWatch();
stopWatch.start("查询加量算法");
// 模拟查询加量算法方法
TimeUnit.SECONDS.sleep(1L);
stopWatch.stop();
stopWatch.start("计算流程");
TimeUnit.SECONDS.sleep(2L);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}
StopWatch '': running time (millis) = 3015
-----------------------------------------
ms % Task name
-----------------------------------------
01013 034% 查询加量算法
02002 066% 计算流程
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
package com.mysql.jdbc;
import java.sql.DriverManager;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
String url = "jdbc:mysql://localhost:3306/test?user=root&password=root"; //定义连接数据库的url
//一、获取mysql的数据库连接对象
Connection conn = DriverManager.getConnection(url);
//二、获取SQL语句执行对象
Statement statement = conn.createStatement();
//三、执行SQL语句
int result = statement.executeUpdate("sql语句");
将服务中所有.jar包下META-INF/services/java.sql.Driver文件中的实现类(eg:mysql的com.mysql.jdbc.Driver)加载到内存list中,并在getConnection中从list中获取实例对象
public class DriverManager {
static {
loadInitialDrivers();
}
public static Connection getConnection(String url)
///
}
}
2.4.1、通过spi,获取所有Driver接口实现类对象,放入list
1)、DriverManager.getConnection(url),因为getConnection是静态方法,会触发DriverManager类的首次主动使用,会调用()即调用static{}中loadInitialDrivers
private static void loadInitialDrivers() {
// 一、load
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();
// 二、hasNext
while(driversIterator.hasNext()) {
// 三、next
driversIterator.next();
}
}
2)、load():指定上下文类加载器加载作为Driver接口的具体实现类com.mysql.jdbc.Driver的加载器
public static <S> ServiceLoader<S> load(Class<S> service) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();//上下文加载器,去加载Deiver接口的实现类
return ServiceLoader.load(service, cl);
}
SPI接口实现类的加载需要破坏双亲委派模型。
3)、hasNext():按行读取所有.jar中含有"META-INF/services/com.sql.Driver"的file文件内容,将实现类全路径加入Iterator
private boolean hasNextService() {
//1.首次加载为null
if (configs == null) {
// 2.这里的fullName = "META-INF/services/" + com.sql.Driver
String fullName = PREFIX + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
// 3.获取url(不重要)
configs = loader.getResources(fullName);
}
while ((pending == null) || !pending.hasNext()) {
// 4.会读取所有.jar,含有"META-INF/services/com.sql.Driver"的file文件
// 一行一行的读取file的内容,比如读取com.msql.jdbc.Driver,将Diver接口所有的实现类的全路径放Iterator
Iterator<String> pending = parse(service, configs.nextElement());//parseLine(service,names)
}
nextName = pending.next();
return true;
}
4)、next():创建Driver接口实现类的实例对象,并将实例对象放入list,便于后续getConnection时从list中获取实例对象
private S nextService() {
// 1.Diver接口实现类的全路径,比如com.mysql.jdbc.Driver
String cn = nextName;
nextName = null;
Class<?> c = null;
try {
// 2.使用上下文加载器,创建class(com.mysql.jdbc.Driver)类对象
c = Class.forName(cn, false, loader);
}
try {
// 3.生成Driver实现类的实例对象(重要)
S p = service.cast(c.newInstance());
providers.put(cn, p);
return p;
}
}
// 这里特别重要的一个点是c.newInstance(),即对实现类Diver创建实例
根据类的首次主动使用原则,会触发com.mysql.jdbc.Driver类的static{}
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
DriverManager.registerDriver(new Driver());
}
}
}
//registerDriver方法,会将com.mysql.jdbc.Driver实例,加入list中,便于后续getConnection的获取
public static synchronized void registerDriver(java.sql.Driver driver){
/* Register the driver if it has not already been added to our list */
if(driver != null) {
//CopyOnWriteArrayList registeredDrivers
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
}
}
public static Connection getConnection(String url)
return (getConnection(url, info, Reflection.getCallerClass()));
}
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
// CopyOnWriteArrayList registeredDrivers
// 这里遍历上述2.4.1中存入list的所有Driver接口的实现类对象,然后connect,这里以com.mysql.jdbc.Driver的connect
// 为例
for(DriverInfo aDriver : registeredDrivers) {
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
}
public class NoRegisterDriver{
public Connection connect(String url, Properties info) throws SQLException {
// 1.一般我们都会使用.properties将数据库连接的url、port、user、password等属性放在文件中使用Properties加载
Properties props = null;
// 2.创建mysql的数据库连接(localhost即ip地址信息、port端口信息等,都可以从String url = "jdbc:mysql://localhost:3306/test?user=root&password=root"中解析)
com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url);
return newConn;
}
}
}
}
protected static Connection getInstance(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) {
// 底层还是通过反射,Constructor ctor.newInstance(args)创建的JDBC4对应的mysql的con对象
}
至此,就得到了mysql数据库的con连接对象
3.1 定义client模块,内含自定义接口Myservice以及其实现类MyServiceImpl
public interface MyService {
public void show();
}
public class MyServiceImpl implements MyService {
@Override
public void show() {
System.out.println("load MyServiceImpl spi");
}
}
3.2 将自定义接口实现类全路径,作为内容写在清单文件file(自定义接口全路径)中
3.3 定义service模块
<dependencies>
<dependency>
<groupId>CodeBetter</groupId>
<artifactId>com.mjp.client</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
public static void main(String[] args) {
ServiceLoader<MyService> services = ServiceLoader.load(MyService.class);
for (MyService service : services) {
service.show();//load MyServiceImpl spi
}
}
spi服务发现机制,更具有插拔性。
public void test() {
List<Integer> list1 = Lists.newArrayList(1, 2);
List<Integer> list2 = Lists.newArrayList(3, 4);
List<List<Integer>> res = Lists.cartesianProduct(list1, list2);
System.out.println(res);//[[1, 3], [1, 4], [2, 3], [2, 4]]
}
public void test() {
Set<Integer> set = Sets.newHashSet(1, 2, 3);
//[1]
//[2]
//[3]
Set<Set<Integer>> combinations1 = Sets.combinations(set, 1);//1是表示子集中元素个数为1的子集
//[1, 2]
//[1, 3]
//[2, 3]
Set<Set<Integer>> combinations2= Sets.combinations(set, 2);
//[1, 2, 3]
Set<Set<Integer>> combinations3= Sets.combinations(set, 3);
}
差集、交集等
public void test() {
Map<Integer, String> map = Maps.asMap(Sets.newHashSet(1, 2, 3), k -> "hello" + k);
System.out.println(map);//{1=hello1, 2=hello2, 3=hello3}
}
public void test() {
Map<String, Integer> sourceMap = new HashMap<>();
sourceMap.put("wxx", 18);
sourceMap.put("mjp", 20);
Map<String, Integer> targetMap = Maps.transformValues(sourceMap, sourceV -> sourceV + 1);
System.out.println(targetMap);//{mjp=21, wxx=19}
}
ImmutableMap map = Maps.fromProperties();//Properties
这样就不用使用Map
否则就需要遍历list,然后再new一个新的newList,然后使用map.putIfAbsent方式一个一个遍历元素不存在再放入newList
直接遍历list,put即可
public void test() {
Multimap<String, String> multimap = LinkedHashMultimap.create();
multimap.put("1","1");
multimap.put("1","2");
System.out.println(multimap);//{1=[1, 2]}
Collection<String> strings = multimap.get("1");
Multimap<String, User> multimap = LinkedHashMultimap.create();
multimap.put("1",new User("wxx", 18));
multimap.put("1",new User("mjp", 20));
System.out.println(multimap);//{1=[User(name=wxx, age=18), User(name=mjp, age=20)]}
}
public void test() {
Table<String, String, String> table = HashBasedTable.create();
table.put("Language", "Java", "jdk1.8");
table.put("Language", "python", "3.5");
table.put("DataBase", "MySQL", "8.0");
table.put("DataBase", "Oracle", "x");
System.out.println(table);//{Language={Java=jdk1.8, python=3.5}, DataBase={MySQL=8.0, Oracle=x}}
// row
Map<String, String> languageMap = table.row("Language");
System.out.println(languageMap);//{Java=jdk1.8, python=3.5}
// col
Map<String, String> dataBaseMap = table.column("Java");
System.out.println(dataBaseMap);//{Language=jdk1.8}
// entry
Set<Table.Cell<String, String, String>> cells = table.cellSet();
for (Table.Cell<String, String, String> cell : cells) {
System.out.println(String.format("rowKey:[%s], colKey:[%s], val:[%s]",
cell.getRowKey(), cell.getColumnKey(), cell.getValue()));
}
// toRowMap
Map<String, Map<String, String>> map = table.rowMap();
System.out.println(map);//{Language={Java=jdk1.8, python=3.5}, DataBase={MySQL=8.0, Oracle=x}}
}
Range.atLeast(2);
Range.greaterThan(2);
Range.atMost(5);
Range.lessThan(5);
Range.open(1, 5);
Range.openClosed(1, 5);
Range.closedOpen(1, 5);
Range.closed(1, 5);
Range.all();
[0,60):不及格
[60,70):及格
[70,80):中等
public void test() {
TreeRangeMap<Integer, String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closedOpen(0, 60), "不及格");
rangeMap.put(Range.closedOpen(60, 70), "及格");
rangeMap.put(Range.closedOpen(70, 80), "中等");
rangeMap.put(Range.closedOpen(80, 90), "良好");
rangeMap.put(Range.closed(90, 100), "优秀");
System.out.println(rangeMap);//[[0..60)=不及格, [60..70)=及格, [70..80)=中等, [80..90)=良好, [90..100]=优秀]
String res = rangeMap.get(78);
System.out.println(res);//中等
}
不可变map、list即不允许再添加 元素,否则报错
public void test() {
ImmutableMap<String, Integer> immutableMap = ImmutableMap.<String, Integer>builder()
.put("wxx", 17)
.put("mjp", 18)
.build();
System.out.println(immutableMap);
}
public void test() {
List<Integer> list = Lists.newArrayList(1, 3, 5, 2, null);
Collections.sort(list, Ordering.natural().nullsLast());
System.out.println(list);//[1, 2, 3, 5, null]
Collections.sort(list, Ordering.natural().thenComparing());
}
@AllArgsConstructor
public class MyLRU<K, V> extends LinkedHashMap<K,V>{
private Integer limit;
public MyLRU(int limit) {
super(16, 0.75f, true);//必须要有
this.limit = limit;
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > limit;
}
}
public void test() {
MyLRU<String, String> lru = new MyLRU<>(3);
lru.put("1", "1");
lru.put("2", "2");
lru.put("3", "3");
// 右进,左出
System.out.println(lru);//{1=1, 2=2, 3=3}
lru.put("4", "4");
System.out.println(lru);//{2=2, 3=3, 4=4}
lru.get("2");
System.out.println(lru);//{3=3, 4=4, 2=2}最新最少使用的在左边
lru.put("5","5");
System.out.println(lru);//{4=4, 2=2, 5=5}
}
1、原理
put -> afterNodeInsertion -> removeEldestEntry(如果size > limt了就会触发removeNode方法) -> removeNode
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
removeNode(hash(key), key, null, false, true);
}
1、这里的lru是强引用。也就是说存入的数据,GC无法直接回收。可能造成OOM
@Test
public void test() {
MyLRU<String, byte[]> cache = new MyLRU<>(100);
for (int i = 0; i < 100; i++) {
cache.put(String.valueOf(i), new byte[1024 * 1024 * 2]);//2M,指定-Xmx128M -Xms64M -XX:+PrintGCDetails,则cache放不到100个元素,估计60个左右元素就会OOM,java.lang.OutOfMemoryError: Java heap space
System.out.println(i);
}
}
2、使用软引用即可(当内存不够用时,会触发GC将软引用删除)
@AllArgsConstructor
public class MyLRU<K, V> extends LinkedHashMap<K, SoftReference<V>>{
private Integer limit;
public MyLRU(int limit) {
super(16, 0.75f, true);
this.limit = limit;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, SoftReference<V>> eldest) {
return size() > limit;
}
}
public void test() {
MyLRU<String, byte[]> cache = new MyLRU<>(100);
for (int i = 0; i < 100; i++) {
cache.put(String.valueOf(i), new SoftReference<>(new byte[1024 * 1024 * 2]));//2M,指定-Xmx128M -Xms64M -XX:+PrintGCDetails,因为Value是弱引用的,当cache存储60个左右元素时,发现内存不够了,则会GC,回收若引用的内容,不会造成OOM
System.out.println(i);
}
}
// 如果弱引用内容被回收了,则get时
SoftReference<byte[]> softReference = cache.get("1");
if (softReference == null) {
//去db查询真实的数据
return ---
} else {
return softReference.get();
}
3、补充:虚引用PhantomReference:
public void run() {
FileCleaningTracker.Tracker tracker = (FileCleaningTracker.Tracker)FileCleaningTracker.this.q.remove();
FileCleaningTracker.this.trackers.remove(tracker);
if (!tracker.delete()) {
FileCleaningTracker.this.deleteFailures.add(tracker.getPath());
}
tracker.clear();
}
/**
* Removes the next reference object in this queue, blocking until one
* becomes available.
*/
public Reference<? extends T> remove() throws InterruptedException {
return remove(0);
}
这里的cache都是进程级别的不是分布式的
register:类似MQ的subscriber订阅者即消费组
post:类似MQ的Provider类中的send方法
@Subscribe:类似于Consumer类中的receive方法
如果receive方法耗时特别长,建议异步起线程执行。否则影响下一个event的接收,反而影响bus
场景一:event本身为字符串
public class Provider {
public static void main(String[] args) {
EventBus eventBus = new EventBus();
// subscriber订阅者
eventBus.register(new MyConsumer());
// send
eventBus.post("mjp");
}
}
public class MyConsumer {
@Subscribe
public void receive(String event){
System.out.println(event);
}
}
场景二:event本身为类
public class Provider {
public static void main(String[] args) {
EventBus eventBus = new EventBus();
// subscriber订阅者
eventBus.register(new MyConsumer());
// send
eventBus.post(new User("mjp", 18));
}
}
public class MyConsumer {
@Subscribe
public void receive(User user){
System.out.println(user.getName());
}
}
public class Provider {
public static void main(String[] args) {
// 匿名内部类,相当于消费者receive消费方法抛出异常了。会走到{}处理,不影响总的Bus
final EventBus eventBus = new EventBus((e, context) -> {
log.error("consumer:[{}], receive方法:[{}], msg:[{}], 流程异常",
GsonUtil.toJsonString(context.getSubscriber()),
GsonUtil.toJsonString(context.getSubscriberMethod()),
GsonUtil.toJsonString(context.getEvent()), e);
});
// subscriber订阅者
eventBus.register(new MyConsumer());
// send
eventBus.post(new User("mjp", 0));
}
}
public class MyConsumer {
@Subscribe
public void myReceive(User user){
if (user.getAge() < 1) {
throw new IllegalArgumentException("年龄错误");
}
}
}
背景:
eventBus.register(new MyConsumer());
eventBus.register(new MyConsumer2());
// send
eventBus.post(new User("mjp", 0));
eventBus.post("hello");
public class MyConsumer {
@Subscribe
public void myReceive(User event) throws InterruptedException {
TimeUnit.SECONDS.sleep(5L);//耗时特别久
System.out.println(event.getName());
}
}
public class Provider {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(2);
AsyncEventBus asyncEventBus = new AsyncEventBus(threadPool, ((e, context) -> {
log.error("consumer:[{}], receive方法:[{}], msg:[{}], 流程异常",
GsonUtil.toJsonString(context.getSubscriber()),
GsonUtil.toJsonString(context.getSubscriberMethod()),
GsonUtil.toJsonString(context.getEvent()), e);
}));
// subscriber订阅者
asyncEventBus.register(new MyConsumer());
asyncEventBus.register(new MyConsumer2());
// send
asyncEventBus.post(new User("mjp", 0));
asyncEventBus.post("hello");
}
}
guava的eventbus是个进程内级别的,无法跨进程即不是分布式的(Kafka、RockMQ)
建议使用:
服务内部解耦:落数据模块、计算模块、合单模块。彼此之间是进程级别的,都会在一台服务的Java进程中执行,没啥问题
不建议使用:returnplan服务调用oih服务,这种要是有Kafka
高并发环境下不建议使用,因为可能造成线程池拒绝
public void test1() throws IOException {
File file1 = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceA");//必须存在
File file2 = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceB");//不存在会创建
Files.copy(file1, file2);
}
本质相当于将sourceB文件名称换为sourceC
public void test1() throws IOException {
File file1 = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceB");
File file2 = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceC");
Files.move(file1, file2);
}
public void test1() throws IOException {
File file2 = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceC");
List<String> strings = Files.readLines(file2, UTF_8);
String res = Joiner.on("\n").join(strings);
System.out.println(res);//结果和在文件中一样,还是换行展示的字符串
}
public void test1() throws IOException {
File file = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceC");
CharSource charSource = Files.asCharSource(file, UTF_8);
String res = charSource.read();
System.out.println(res);
}
source file文件的内容如下
i
love
java 1314
public void test1() throws IOException {
File file = new File("D:\\CodeBetter\\src\\main\\resources\\io\\source");
CharSource charSource = Files.asCharSource(file, UTF_8);
LineProcessor<List<Integer>> listLineProcessor = new LineProcessor<List<Integer>>() {
private final List<Integer> lineLengthList = new ArrayList<>();
@Override
public boolean processLine(String s) throws IOException {
// 获取file文件每行的字符个数,将长度添加至list中,如果遇到空行,则结束对文件的处理
if (s.length() == 0) {
return false;
}
lineLengthList.add(s.length());
return true;
}
@Override
public List<Integer> getResult() {
return lineLengthList;
}
};
List<Integer> lineLengthList = charSource.readLines(listLineProcessor);
System.out.println(lineLengthList);//[1, 4]因为第三行是空行,长度为0,return false,则后面的行都不再解析
}
public void test1() throws IOException {
File file = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceA");
String s = "i" +
"\n" +
"love" +
"\n" +
"java";
Files.asCharSink(file, UTF_8).write(s);//每次执行都是从头开始覆盖写
}
public void test1() throws IOException {
File file = new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceA");
String s1 = "mjp";
CharSink charSink = Files.asCharSink(file, UTF_8, FileWriteMode.APPEND);
charSink.write(s1);
String s2 = "wxx";
charSink.write(s2);
}
文件内容为mjpwxx
递归遍历查找rootFile下的所有文件和文件夹
public void test1() throws IOException {
File rootFile = new File("D:\\CodeBetter\\src\\main\\java\\com");
Traverser<File> fileTraverser = Files.fileTraverser();
Iterable<File> fileIterable = fileTraverser.depthFirstPreOrder(rootFile);
fileIterable.forEach(f -> {
if (f.isFile()) {
System.out.println(f);
}
});
}
public void test1() throws IOException {
try {
throw new IOException("read error");
} catch (IOException e) {
throw e;
} finally {
try {
throw new IOException("close error");//close关闭资源中发送了异常
} catch (Exception e) {
throw e;
}
}
}
public void test() throws IOException {
try(FileInputStream fileInputStream = new FileInputStream(new File("a"))) {
fileInputStream.read();
} catch (IOException e) {
throw new IOException("read error");
}
}
try-with形式会自动finally关闭资源,原理是InputStream实现了Closeable接口,重写了close()方法
public void close() throws IOException {
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}
以上方式都有个问题即:在close资源的时候如果也发送了异常,则close异常会覆盖掉read异常
java.io.IOException: close error//只有close时异常,没有read时候的异常了
public void test1() throws Exception {
Closer closer = Closer.create();
ByteSource byteSource = Files.asByteSource(new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceA"));
try {
InputStream inputStream = closer.register(byteSource.openStream());
closer.register(inputStream);
} catch (Exception e) {
throw closer.rethrow(e);
} finally {
closer.close();
}
}
这样在close异常的时候,也不会覆盖try中的异常,2个异常都会抛出来
public void test1(){
BaseEncoding base64 = BaseEncoding.base64();
String encode = base64.encode("hello".getBytes());
System.out.println(encode);//aGVsbG8=
byte[] bytes = base64.decode(encode);
String decode = new String(bytes);
System.out.println(decode);//hello
}
1、原理
a -> 97 -> 01100001 ->从高位去6位,剩下的不够6位补0(这里需要补4个0) -> 011000 0100000 -> 二进制(6位补0变8位)转为十进制24 16 ->去64位编码表中找24 和 16对应的字符 -> Y Q -> 然后结果再根据补0的个数添加=,2个0对应一个= 即YQ==
public void test1(){
String binary = Integer.toBinaryString(97);
System.out.println(binary);//1100001
}
public void test1(){
Integer value = Integer.valueOf("1100001", 2);
System.out.println(value);//97
}
上方式都有个问题即:在close资源的时候如果也发送了异常,则close异常会覆盖掉read异常
java.io.IOException: close error//只有close时异常,没有read时候的异常了
public void test1() throws Exception {
Closer closer = Closer.create();
ByteSource byteSource = Files.asByteSource(new File("D:\\CodeBetter\\src\\main\\resources\\io\\sourceA"));
try {
InputStream inputStream = closer.register(byteSource.openStream());
closer.register(inputStream);
} catch (Exception e) {
throw closer.rethrow(e);
} finally {
closer.close();
}
}
这样在close异常的时候,也不会覆盖try中的异常,2个异常都会抛出来
public void test1(){
BaseEncoding base64 = BaseEncoding.base64();
String encode = base64.encode("hello".getBytes());
System.out.println(encode);//aGVsbG8=
byte[] bytes = base64.decode(encode);
String decode = new String(bytes);
System.out.println(decode);//hello
}
1、原理
a -> 97 -> 01100001 ->从高位去6位,剩下的不够6位补0(这里需要补4个0) -> 011000 0100000 -> 二进制(6位补0变8位)转为十进制24 16 ->去64位编码表中找24 和 16对应的字符 -> Y Q -> 然后结果再根据补0的个数添加=,2个0对应一个= 即YQ==
public void test1(){
String binary = Integer.toBinaryString(97);
System.out.println(binary);//1100001
}
public void test1(){
Integer value = Integer.valueOf("1100001", 2);
System.out.println(value);//97
}