java冷门小功能代码收集

1. 获取本地文件的Mimetype

import java.net.URLConnection;

String contentType = URLConnection.getFileNameMap().getContentTypeFor(filePath);

2. 获取超大图片的尺寸

import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;

try (
    FileImageInputStream inputStream = new FileImageInputStream(new File(imageFilePath));
    ) {
    Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream);
    if (readers.hasNext()) {
    	ImageReader reader = readers.next();
    	reader.setInput(inputStream);
    	int width = reader.getWidth(reader.getMinIndex(); //图片宽度
    	int height = reader.getHeight(reader.getMinIndex()); //图片高度

	}
  	inputStream.flush();
} catch (Exception e) {
	log.error("读取图片时异常", e);
}

3. 使用itextpdf获取pdf文件的尺寸

import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfReader;

PdfReader pdfReader = null;
try {
	pdfReader = new PdfReader(pdfPath);
	Rectangle pageSize = pdfReader.getPageSize(1); 1表示首页
	int width = pageSize.getWidth(); //宽高
	int height = pageSize.getHeight(); //高度
} catch (Exception e) {
	log.error("读取pdf时异常", e);
} finally {
	if (pdfReader != null) {
		pdfReader.close();
	}
}

4. 原生代码复制文件

import java.io.File;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
//StandardCopyOption.REPLACE_EXISTING覆盖已存在的文件
Files.copy(new File(videoFormat.getParent(), videoFormat.getName()).toPath(), new File(outFilePath).toPath(), StandardCopyOption.REPLACE_EXISTING);

5.单例模式在单例类中加入下面的方法可以防止反序列化漏洞

//反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不再单独创建新对象。
private Object readResolve() throws ObjectStreamException {
	return instance;
}

6.解决跨域问题原生代码

public static void originEnable(HttpServletRequest request, HttpServletResponse response) {
	String origin = request.getHeader("Origin");
	if (origin != null && !origin.equals("")) {
		//带cookie的时候,origin必须是全匹配,不能使用*
		response.addHeader("Access-Control-Allow-Origin", origin);
	}
	//允许提交请求的方法,*表示全部允许
	//GET, POST, PUT, DELETE, PATCH...
	response.addHeader("Access-Control-Allow-Methods", "*");

	//支持所有自定义头
	if (headers != null && !headers.equals("")) {
		//Content-Type, x-requested-with, X-Custom-Header, Custom-Access-Token...
		response.addHeader("Access-Control-Allow-Headers", headers);
	}
	//预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检
	response.addHeader("Access-Control-Max-Age", "3600");
}

7.获取当前ISODATETIME格式的时间字符串

//yyyy-MM-ddTHH:mm:ss
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
			.parseCaseInsensitive()
			.append(DateTimeFormatter.ISO_LOCAL_DATE)
			.appendLiteral('T')
			.appendPattern("HH:mm:ss")
			.toFormatter();
		String isoDateTime = LocalDateTime.now(ZoneId.of("+8")).format(formatter);
		System.out.println(isoDateTime);

8.字符串脱敏

/**
 * @param source 源字符串
 * @param start 脱敏开始位置(包含)允许负数,负数即为从右边数
 * @param end 脱敏结束位置(不包含)允许负数,负数即为从右边数
 * @return 脱敏后的字符串
 */
public static String desense(String source, int start, int end) {
	if (source == null || "".equals(source)) {
		return source;
	}
	int length = source.length();
	if (start < 0) {
		start += length;
	}
	if (start < 0) {
		start = 0;
	}
	if (end < 0) {
		end += length + 1;
	}
	if (end < 0) {
		end = length;
	}
	if (start - length > 0) {
		start = length;
	}
	if (end - length > 0) {
		end = length;
	}
	if (start > end) {
		int t = start;
		start = end;
		end = t;
	}
	if (start == end) {
		return source;
	}
	String pre = source.substring(0, start);
	String suff = source.substring(end);
	StringBuilder stars = new StringBuilder();
	for (int i = 0; i < end - start; i++) {
		stars.append("*");
	}
	return pre + stars.toString() + suff;
}

9.判断脱敏字符串是否与明文匹配

/**
 * 判断脱敏字符串是否与明文匹配
 * @param naked 明文字符串
 * @param occlude 脱敏字符串, *表示0个或多个字符
 * @return true,匹配;false,不匹配
 */
 public static boolean like(String naked, String occlude) {
 	if (StringUtils.isEmpty(naked) || StringUtils.isEmpty(occlude)) {
		return false;
	}
	if (!occlude.contains("*")) {
		return naked.equals(occlude);
	}
	//occludeArr.length至少为2
	String[] occludeArr = occlude.split("\\*+", -1);
	String start = occludeArr[0];
	if (StringUtils.isNotEmpty(start)) {
		int index = naked.indexOf(start);
		if (index != 0) {
			return false;
		}
		naked = naked.substring(start.length());
	}

	String end = occludeArr[occludeArr.length - 1];
	if (StringUtils.isNotEmpty(end)) {
		int lastIndex = naked.lastIndexOf(end);
		if (naked.length() - lastIndex - end.length() != 0) {
			return false;
		}
		naked = naked.substring(0, lastIndex);
	}
	if (occludeArr.length < 3) {
		//无中间段,返回true
		return true;
	}

	for (int i = 1, int loop = occludeArr.length - 1; i < loop; i++) {
		String middle = occludeArr[i];
		if (StringUtils.isEmpty(middle)) {
			continue;
		}
		if (naked.isEmpty()) {
			return false;
		}
		int index = naked.indexOf(middle);
		if (index < 0) {
			return false;
		}
		naked = naked.substring(index + middle.length());
	}
	return true;
}

10.从给定的Class类获取JAR文件的完整路径

/**
 * 从给定的Class类获取JAR文件的完整路径
 * @param clazz 类实例
 * @return jar包在本机的绝对路径
 */
public static String getJarFilePath(Class<?> clazz) {
    try {
        return getProtectionDomain(clazz);
    } catch (Exception e) {
    }
    return getResource(clazz);
}

private static String getProtectionDomain(Class<?> clazz) throws URISyntaxException {
	URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
	return Paths.get(url.toURI()).toString();
}

private static String getResource(Class<?> clazz) {
	URL resource = clazz.getResource(clazz.getSimpleName() + ".class");
	if (resource == null) {
        throw new RuntimeException("class resource is null");
    }
	String url = resource.toString();
	System.out.println(url);
	if (url.startsWith("jar:file:")) {
		String path = url.replaceAll("^jar:(file:.*[.]jar)!/.*", "$1");
		try {
            return Paths.get(new URL(path).toURI()).toString();
        } catch (Exception e) {
            throw new RuntimeException("Invalid Jar File URL String");
        }
	}
	throw new RuntimeException("Invalid Jar File URL String");
}

11.获取项目里的资源输入流

支持本地项目、war包、jar包

public class JarUtils {
	/**
	 * 获取项目里的资源输入流
	 * @param sourcePath 项目编译后classes目录下的文件路径, 如application.properties、com/xxx/util/JarUtils.class
	 * @return null 如果未找到文件
	 */
	public static InputStream getResourceAsStream(String sourcePath) {
		return JarUtils.class.getClassLoader().getResourceAsStream(sourcePath);
	}
}

12.用 Jsoup 删除 html 中的 script 脚本

/**
 * 删除html中的script标签
 * @param html
 * @return
 */
public static String safeHtml(String html) {
    return safeHtml(html, null);
}

/**
 * 删除html中的script标签
 * @param html
 * @param function 如果返回true,则不再处理当前元素及其子元素
 * @return
 */
public static String safeHtml (String html, Function<Element, Boolean> function) {
    if (StringUtils.isEmpty(html)) {
        return html;
    }
    Document doc = Jsoup.parse(html);
    if (doc == null) {
        return html;
    }
    List<Node> nodes = doc.childNodes();
    if (nodes == null || nodes.isEmpty()) {
        return html;
    }
    removeScript(nodes, function);
    return doc.html();
}

private static final Pattern XSS_JS_PATTERN = Pattern
        .compile("(j(\\s)*a(\\s)*v(\\s)*a(\\s)*s(\\s)*c(\\s)*r(\\s)*i(\\s)*p(\\s)*t(\\s)*:)");

private static void removeScript (List<Node> nodes, Function<Element, Boolean> function) {
    for (Node node : nodes) {
        if (node.nodeName().equals("#comment")) {
            //移除注释标签
            if (node.hasParent()) {
                node.remove();
            }
        } else if (node instanceof Element) {
            Element ele = (Element) node;
            if (function != null && function.apply(ele)) {
                continue;
            }
            if (ele.tag().normalName().equals("script")) {
                if (ele.hasParent()) {
                    ele.remove();
                }
            } else {
                Attributes attributes = ele.attributes();
                for (Attribute attr : attributes) {
                    if (Attribute.isBooleanAttribute(attr.getKey())) {
                        continue;
                    }
                    if (StringUtils.isEmpty(attr.getValue())) {
                        continue;
                    }
                    if (XSS_JS_PATTERN.matcher(attr.getValue().toLowerCase()).find()) {
                        attr.setValue("javascript:void(0);");
                    }
                }
                removeScript(ele.childNodes(), function);
            }
        }
    }
}

//测试
String html = "";
String safed = safeHtml(html , ele -> {
    if (ele.tag().normalName().equals("style")) {
        if (ele.hasParent()) {
            ele.remove();//移除style及其后代标签
        }
        return true;//返回true,表示不再处理当前元素及其子元素
    } else if (ele.tag().normalName().equals("a")) {
        if (ele.hasParent()) {
            ele.tagName("span");//a标签替换为span标签
        }
        return true;
    }
    return false;
});

13.正规化空白字符

org.apache.commons.lang3.StringUtils.normalizeSpace(String)

14.正规化python生成的json字符串

public static String normalPythonJson (String pythonJson) {
    if (pythonJson == null) {
        return null;
    }
    char[] cs = pythonJson.toCharArray();
    StringBuilder sb = new StringBuilder();
    
    for (int i = 0; i < cs.length; i++) {
        char c = cs[i];
        sb.append(c);
        if (c == '\\') {
            i++;
            if (i < cs.length) {
                char d = cs[i];
                if (d == 'u') {
                    sb.append(d);
                } else if (d == '\\') {
                	sb.append(c);
                    i--;
                } else {
                    sb.append(c).append(d);
                }
            } else {
                sb.append(c);
            }
        }
    }
    return sb.toString();
}

15.判断字符串中是否包含4字节的字符

如果mysql字段的字符集为utf-8,而sql查询参数包含只属于utf8_mb4的字符,则查询报错

/**
 * 判断字符串中是否包含4字节的字符
 * @param str
 * @return
 */
public static boolean contains4byte (String str) {
    if (str == null || str.isEmpty()) {
        return false;
    }
    int len = str.length();
    for (int i = 0; i < len; i++) {
        int codePoint = str.codePointAt(i);
        if (codePoint < 0x0000 || codePoint > 0xffff) {
            return true;
        }
    }
    return false;
}

16.获取excel全部文本

public static String getWorkbookText (Workbook wb, Consumer<ExcelExtractor> consumer) {
	ExcelExtractor extractor = null;
	if (wb instanceof HSSFWorkbook) {
		extractor = new org.apache.poi.hssf.extractor.ExcelExtractor((HSSFWorkbook) wb);
	} else if (wb instanceof XSSFWorkbook) {
		extractor = new XSSFExcelExtractor((XSSFWorkbook) wb);
	}
	if (consumer != null) {
		consumer.accept(extractor);
	}
	return extractor.getText();
}

public static void main(String[] args) throws EncryptedDocumentException, IOException {
	try (
			Workbook wb = WorkbookFactory.create(new File("/ceshi", "test123.xlsm"));
			) {
		String text = getWorkbookText(wb, e -> {
			e.setIncludeSheetNames(true);
			e.setFormulasNotResults(false);
			e.setIncludeHeadersFooters(true);
			e.setIncludeCellComments(false);
		});
		System.out.println(text);
	}
}

17.Mysql 获取本周本月本季度本半年本年的第一天日期

select '本周第一天' as var_name, date_sub(current_date(), interval WEEKDAY(current_date()) day) var_value
union all
select '本月第一天' as var_name, date_sub(current_date(), interval DAYOFMONTH(current_date()) - 1 day) var_value
union all
select '本季度第一天' as var_name, date_sub(date_sub(DATE(current_date()), interval DAYOFMONTH(current_date()) - 1 day), interval month(current_date()) - (QUARTER(current_date()) - 1) * 3 - 1 month) var_value
union all
select '本半年第一天' as var_name, date_sub(date_sub(DATE(current_date()), interval DAYOFMONTH(current_date()) - 1 day), interval (month(current_date()) - 1) mod 6 month) var_value
union all
select '本年第一天' as var_name, date_sub(date_sub(DATE(current_date()), interval DAYOFMONTH(current_date()) - 1 day), interval month(current_date()) - 1 month) var_value

18.解码Unicode

可以解码unicode与普通字符混合的字符串

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Translates escaped Unicode values of the form \\u+\d\d\d\d back to
 * Unicode. It supports multiple 'u' characters and will work with or
 * without the +.
 *
 * 代码摘抄自 org.apache.commons.text.translate.UnicodeUnescaper
 */
public final class UnicodeUnescapeUtils {
	

    /**
     * Helper for non-Writer usage.
     * @param input CharSequence to be translated
     * @return String output of translation
     */
    public static String translate(final CharSequence input) {
        if (input == null) {
            return null;
        }
        try {
            final StringWriter writer = new StringWriter(input.length() * 2);
            translate(input, writer);
            return writer.toString();
        } catch (final IOException ioe) {
            // this should never ever happen while writing to a StringWriter
            throw new RuntimeException(ioe);
        }
    }
	
    /**
     * Translate an input onto a Writer. This is intentionally final as its algorithm is
     * tightly coupled with the abstract method of this class.
     *
     * @param input CharSequence that is being translated
     * @param out Writer to translate the text to
     * @throws IOException if and only if the Writer produces an IOException
     */
	public static void translate(final CharSequence input, final Writer out) throws IOException {
		if (out == null) {
			throw new IllegalArgumentException("The Writer must not be null");
		}
        if (input == null) {
            return;
        }
        int pos = 0;
        final int len = input.length();
        while (pos < len) {
            final int consumed = translate(input, pos, out);
            if (consumed == 0) {
                // inlined implementation of Character.toChars(Character.codePointAt(input, pos))
                // avoids allocating temp char arrays and duplicate checks
                final char c1 = input.charAt(pos);
                out.write(c1);
                pos++;
                if (Character.isHighSurrogate(c1) && pos < len) {
                    final char c2 = input.charAt(pos);
                    if (Character.isLowSurrogate(c2)) {
                      out.write(c2);
                      pos++;
                    }
                }
                continue;
            }
            // contract with translators is that they have to understand codepoints
            // and they just took care of a surrogate pair
            for (int pt = 0; pt < consumed; pt++) {
                pos += Character.charCount(Character.codePointAt(input, pos));
            }
        }
    }
	
	private static int translate(final CharSequence input, final int index, final Writer out) throws IOException {
        if (input.charAt(index) == '\\' && index + 1 < input.length() && input.charAt(index + 1) == 'u') {
            // consume optional additional 'u' chars
            int i = 2;
            while (index + i < input.length() && input.charAt(index + i) == 'u') {
                i++;
            }

            if (index + i < input.length() && input.charAt(index + i) == '+') {
                i++;
            }

            if (index + i + 4 <= input.length()) {
                // Get 4 hex digits
                final CharSequence unicode = input.subSequence(index + i, index + i + 4);

                try {
                    final int value = Integer.parseInt(unicode.toString(), 16);
                    out.write((char) value);
                } catch (final NumberFormatException nfe) {
                    throw new IllegalArgumentException("Unable to parse unicode value: " + unicode, nfe);
                }
                return i + 4;
            }
            throw new IllegalArgumentException("Less than 4 hex digits in unicode value: '"
                    + input.subSequence(index, input.length())
                    + "' due to end of CharSequence");
        }
        return 0;
    }

}

19.不依赖 Springboot 使用 HibernateValidator

import java.util.Iterator;
import java.util.Locale;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

import org.hibernate.validator.HibernateValidator;

/**
 * 验证对象字段工具
 */
public final class ValidationUtils {

    private ValidationUtils() {}
    
    private static final Validator VALIDATOR = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(true) //快速失败,即有一个字段验证失败就返回
            .defaultLocale(Locale.SIMPLIFIED_CHINESE) //使用简体中文提示
            .buildValidatorFactory()
            .getValidator();
    
    public static Validator getDefaultValidator () {
        return VALIDATOR;
    }
    
    /**
     * 验证通过,则返回空字符串;验证失败,则返回提示信息
     */
    public static <T> String simpleValidate (T obj) {
        Set<ConstraintViolation<T>> validateSet = getDefaultValidator().validate(obj);
        if (!validateSet.isEmpty()) {
            Iterator<ConstraintViolation<T>> iterator = validateSet.iterator();
            if (iterator.hasNext()) {
                ConstraintViolation<T> next = iterator.next();
                return next.getPropertyPath().toString() + " " + next.getMessage() + ", 无效的值为: " + next.getInvalidValue();
            }
        }
        return "";
    }

}

20.设置下载文件名方法

/**
 * 设置用于下载的 HttpServletResponse 的相关参数,包括:Content-Type、header 等
 *
 * @param fileName 文件名称
 * @param response HttpServletResponse
 */
public static void setDownloadResponse(String fileName, HttpServletResponse response) {
    response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

    try {
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION,
                ATTACHMENT_FILENAME + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
    } catch (UnsupportedEncodingException ex) {
        throw new RuntimeException(ex);
    }

    // 在 POST 请求时,允许前端可以访问响应 header 中的 Content-Disposition
    response.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
}

21.Springboot多数据库配置

以配置clickhouse数据库为例
pom.xml

<dependency>
  <groupId>ru.yandex.clickhouse</groupId>
  <artifactId>clickhouse-jdbc</artifactId>
  <version>0.2.6</version>
  <exclusions>
    <exclusion>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </exclusion>
  </exclusions>
</dependency>
package com.xxx.robot.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
@MapperScan(basePackages = "com.xxx.robot.clickhouse.mapper", sqlSessionTemplateRef = "sqlSessionTemplateClickhouse")
public class ClickhouseDbConfig {

    @Bean(name = "dataSourceClickhouse")
    @ConfigurationProperties(prefix = "spring.datasource.clickhouse")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "sqlSessionFactoryClickhouse")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceClickhouse") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage("com.xxx.robot.clickhouse.entity");
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/xxx/robot/clickhouse/mapper/*Mapper.xml"));
        return bean.getObject();
    }

    @Bean(name = "transactionManagerClickhouse")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSourceClickhouse") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "sqlSessionTemplateClickhouse")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactoryClickhouse") SqlSessionFactory sqlSessionFactory) throws Exception {
        sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

application.properties

# clickhouse
spring.datasource.clickhouse.driver-class-name=ru.yandex.clickhouse.ClickHouseDriver
spring.datasource.clickhouse.jdbc-url=jdbc:clickhouse://192.168.120.12:8123/iir?socket_timeout=9000000
spring.datasource.clickhouse.username=myuser
spring.datasource.clickhouse.password=xxx@!12
spring.datasource.clickhouse.max-idle=10
spring.datasource.clickhouse.max-wait=10000
spring.datasource.clickhouse.min-idle=5
spring.datasource.clickhouse.initial-size=5

22.查找本机第一个非回环IP地址


import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class InetUtils {
	
	private static final Logger log = LoggerFactory.getLogger(InetUtils.class);
	
	private InetUtils () {}
	
	public static String findFirstNonLoopbackHostAddress() {
		InetAddress address = findFirstNonLoopbackAddress();
		if (address == null) {
			return "";
		}
		return address.getHostAddress();
	}

	/**
	 * copy from {@org.springframework.cloud.commons.util.InetUtils}
	 * 查找第一个非回环IP地址
	 * @return
	 */
	public static InetAddress findFirstNonLoopbackAddress() {
		InetAddress result = null;
		try {
			int lowest = Integer.MAX_VALUE;
			for (Enumeration<NetworkInterface> nics = NetworkInterface
					.getNetworkInterfaces(); nics.hasMoreElements();) {
				NetworkInterface ifc = nics.nextElement();
				if (ifc.isUp()) {
					log.trace("Testing interface: " + ifc.getDisplayName());
					if (ifc.getIndex() < lowest || result == null) {
						lowest = ifc.getIndex();
					}
					else if (result != null) {
						continue;
					}

					for (Enumeration<InetAddress> addrs = ifc
							.getInetAddresses(); addrs.hasMoreElements();) {
						InetAddress address = addrs.nextElement();
						if (address instanceof Inet4Address
								&& !address.isLoopbackAddress()) {
							log.trace("Found non-loopback interface: "
									+ ifc.getDisplayName());
							result = address;
						}
					}
				}
			}
		} catch (IOException ex) {
			log.error("Cannot get first non-loopback address", ex);
		}

		if (result != null) {
			return result;
		}

		try {
			return InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			log.warn("Unable to retrieve localhost");
		}

		return null;
	}
	
	/**
	 * ipv4字符串转为long,转为int会出现负数
	 */
	public static long ipToLong (String ipv4) {
		if (ipv4 == null || ipv4.isEmpty()) {
			return 0;
		}
		long l = 0;
		String[] split = ipv4.split("\\.");
		l += Long.parseLong(split[0], 10) << 24;
		l += Long.parseLong(split[1], 10) << 16;
		l += Long.parseLong(split[2], 10) << 8;
		l += Long.parseLong(split[3], 10);
		return l;
	}
	
	/**
	 * long转为ipv4字符串
	 * @param i
	 * @return
	 */
	public static String longToIp (long l) {
		String ip = "";
		ip = ip + ((l >> 24) & 0xFF);
		ip = ip + "." + ((l >> 16) & 0xFF);
		ip = ip + "." + ((l >> 8) & 0xFF);
		ip = ip + "." + (l & 0xFF);
		return ip;
	}
	
	public static void main(String[] args) throws UnknownHostException {
		String nonLoopbackHostAddress = findFirstNonLoopbackHostAddress();
		System.out.println("IP地址:" + nonLoopbackHostAddress);
		long ipToLong = ipToLong(nonLoopbackHostAddress);
		System.out.println(ipToLong);
		String longToIp = longToIp(ipToLong);
		System.out.println(longToIp);
	}

}

23.最快的不重复且公平地获取N个整数区间的随机数

不重复 - 指方法返回数组的元素不重复
公平 - 指方法返回数组的元素出现的概率是相等的

import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

public class RandomUtils {

	public static void main(String[] args) {
		int[] arr = new int[100];
		long nanoTime = System.nanoTime();
		for (int i = 0; i < 10000; i++) {
			int[] randoms = nextInts(0, 100, 100);
//			System.out.println(Arrays.toString(randoms));
			for (int j : randoms) {
				arr[j] = arr[j] + 1;
			}
		}
		//测试性能
		System.out.println(System.nanoTime() - nanoTime);
		//测试公平性
		System.out.println(Arrays.toString(arr));
	}

	/**
	 * 不重复且公平地获取N个整数区间的随机数
	 * @param origin the least value returned
	 * @param bound the upper bound (exclusive)
	 * @param count 
	 * @return the count pseudorandom {@code int} values between the origin
	 *         (inclusive) and the bound (exclusive)
	 */
	public static int[] nextInts(int origin, int bound, int count) {
		if (count <= 0) {
			throw new IllegalArgumentException("count 必须大于 0");
		}
		if (count > bound - origin) {
			throw new IllegalArgumentException("count 不能大于 bound - origin");
		}
		int[] result = new int[count];
		if (count == 1) {
			result[0] = ThreadLocalRandom.current().nextInt(origin, bound);
			return result;
		} else if (count == 2 || count == 3) {
			int pos1 = ThreadLocalRandom.current().nextInt(origin, bound);
			int pos2 = ThreadLocalRandom.current().nextInt(origin, bound - 1);
			if (pos2 >= pos1) {
				pos2 ++;
			}
			result[0] = pos1;
			result[1] = pos2;
			
			if (count == 3) {
				int pos3 = ThreadLocalRandom.current().nextInt(origin, bound - 2);
				if (pos3 >= Math.min(pos1, pos2)) {
					pos3 ++;
				}
				if (pos3 >= Math.max(pos1, pos2)) {
					pos3 ++;
				}
				result[2] = pos3;
			}
			return result;
		}
		IntArray list = new IntArray(count);
		for (int i = 0; i < count; i++) {
			int pos = ThreadLocalRandom.current().nextInt(origin, bound - i);
			if (list.isEmpty()) {
				list.add(pos);
			} else {
				int idx = 0;
				int lastIndex = list.size() - 1;
				for (int item : list.getEle()) {
					if (pos < item) {
						break;
					}
					pos ++;
					idx ++;
					if (idx > lastIndex) {
						break;
					}
				}
				list.add(idx, pos);
			}
			result[i] = pos;
		}
		return result;
	}
	
	private static final class IntArray {
		
		private int size = 0;
		
		private int[] ele;

		IntArray(int fixCapacity) {
			ele = new int[fixCapacity];
		}
		
		void add(int e) {
	        ele[size++] = e;
	    }
		
		void add(int index, int e) {
	        System.arraycopy(ele, index, ele, index + 1, size - index);
	        ele[index] = e;
	        size++;
	    }
		
		int [] getEle () {
			return ele;
		}

	    boolean isEmpty() {
	        return size == 0;
	    }
	    
	    int size() {
	        return size;
	    }
	}

}

24.POI 判断单元格内的文本内容是否超出单元格的宽度

Workbook workbook;
Sheet sheet = workbook.getSheetAt(0);
int beginRowIndex = 0;
int rowSize = sheet.getLastRowNum() + 1;//总行数
int columnIndex = 0;//假设只操作第一列的单元格

int defaultCharWidth = SheetUtil.getDefaultCharWidth(workbook);
DataFormatter dataFormatter = new DataFormatter();
for (int i = beginRowIndex; i < rowSize; i++) {
    Row row = sheet.getRow(i);
    if (row == null) {
        continue;
    }
    Cell cell = row.getCell(columnIndex);
    if (cell == null) {
        continue;
    }
    double cellValueWidth = SheetUtil.getCellWidth(cell, defaultCharWidth, dataFormatter, false);
    int neededColunmnWidth = (int) cellValueWidth * 256;
    int columnWidth = sheet.getColumnWidth(columnIndex);
    System.out.println("单元格的实际宽度:" + columnWidth);
    System.out.println("单元格内的文本所占的宽度:" + neededColunmnWidth);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值