11.HashMap和Hashtable的区别?哪一个对于多线程应用程序更好?
总之,如果你无需关心同步(synchronized)问题,我会建议用HashMap。反之,你可以考虑使用ConcurrentHashMap。
方法一:一行代码搞定 Apache Commons Lang library ArrayUtils.addAll(T[], T…)就是专门干这事的
public class Test12 {
public static void main(String[] args) {
int[] a = {1,2,3};
int[] b = {3,4,5};
int[] c = ArrayUtils.addAll(a, b);
System.out.println(Arrays.toString(c));
}
}
输出
[1, 2, 3, 3, 4, 5]
献上Apache Commons Lang的API文档地址http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/package-summary.html
方法二:非泛型 把下面的Foo替换成你自己的数组类型
public Foo[] concat(Foo[] a, Foo[] b) {
int aLen = a.length;
int bLen = b.length;
Foo[] c= new Foo[aLen+bLen];
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
方法三:泛型
public <T> T[] concatenate (T[] a, T[] b) {
int aLen = a.length;
int bLen = b.length;
@SuppressWarnings("unchecked")
T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen+bLen);
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
注意,泛型的方案不适用于基本数据类型(int,boolean……)
看到这个问题,第一次接触Commons Lang这个东西,其实之前有个问题也用到了这个jar包,但我忽略了,没想到这个问题又来了,所以我觉得有必要了解一下了。去官网下了jar包导入项目后,试了一下方法一,的确可行,ArrayUtils.addAll(T[], T…)源码如下:
public static Object[] addAll(Object[] array1, Object[] array2) {
if (array1 == null) {
return clone(array2);
} else if (array2 == null) {
return clone(array1);
}
Object[] joinedArray = (Object[]) Array.newInstance(array1.getClass().getComponentType(),
array1.length + array2.length);
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
return joinedArray;
}
看看有没有发现,和我们方法三十分相似,不过一个是T类型的,一个是Object类型的,然鹅方法三不支持基本类型,方法一却支持基本类型,所有如果不使用方法一,使用方法三,也建议把T改成Object,就可以使用基本类型了。
在 c++ 中,常见到如下的方法定义(param3 默认为 false)
void MyParameterizedFunction(String param1, int param2, bool param3=false);
那在 java 中,是否也支持这样的定义方式?
答案是否定的,不过我们可以通过多种方式处理这种参数默认值的情况。
方法一:创建者模式(我看不懂,想了解的可以移步)
使用创建者模式,你可以设定部分参数是有默认值,部分参数是可选的如:
Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
.name("Spicoli")
.age(16)
.motto("Aloha, Mr Hand")
.buildStudent();
方法二:构造函数重载(这个我知道)
void foo(String a, Integer b) {
//...
}
void foo(String a) {
foo(a, 0); // here, 0 is a default value for b
}
foo("a", 2);
foo("a");
构造函数重载,对于参数比较少的情况下,比较适合;当参数相对多的时候,可以考虑使用静态工厂方法,或添加一个参数辅助对象。
如果是常规方法重载,可以考虑使用参数辅助对象,或者重命名多种情况(比如说,有多个开银行卡的重载方法,可以根据需要重命名为开交行卡,开招行卡等多种方法)。
方法三:null的传递
当有多个默认参数时,可以考虑传递null,当参数为null时,将参数设为默认值。如:
void foo(String a, Integer b, Integer c) {
b = b != null ? b : 0;
c = c != null ? c : 0;
//...
}
foo("a", null, 2);
方法四:多参数方式
当有多个参数,且某些参数可以忽略不设置的情况下,可以考虑使用多参数方式。
void foo(String a, Integer... b) {
Integer b1 = b.length > 0 ? b[0] : 0;
Integer b2 = b.length > 1 ? b[1] : 0;
//...
}
foo("a");
foo("a", 1, 2);
void foo(String a, Object... b) {
Integer b1 = 0;
String b2 = "";
if (b.length > 0) {
if (!(b[0] instanceof Integer)) {
throw new IllegalArgumentException("...");
}
b1 = (Integer)b[0];
}
if (b.length > 1) {
if (!(b[1] instanceof String)) {
throw new IllegalArgumentException("...");
}
b2 = (String)b[1];
//...
}
//...
}
foo("a"); foo("a", 1); foo("a", 1, "b2");
方法五:使用Map作为方法中的参数
void foo(Map<String, Object> parameters) {
String a = "";
Integer b = 0;
if (parameters.containsKey("a")) {
if (!(parameters.get("a") instanceof Integer)) {
throw new IllegalArgumentException("...");
}
a = (String)parameters.get("a");
}
if (parameters.containsKey("b")) {
//...
}
//...
}
foo(ImmutableMap.<String, Object>of( "a", "a", "b", 2, "d", "value"));
好吧,现在看了我也不知道具体的应用场景在哪。也许过些许时日我倒过头来看看,理解会更深刻。
方法一:使用Math.Random()方法
Math.random()可以产生一个大于等于 0且小于 1的双精度随机数,假设需要产生“0”=随机数<= 10“的随机数,可以这样做:
int num =(int)(Math.random() * 11);
那如何产生“5 <=随机数<= 10”的随机数呢?
int num = 5 + (int)(Math.random() * 6);
生成“min <=随机数<= max”的随机数
int num = min + (int)(Math.random() * (max-min+1));
方法二:使用java.util.Random类
随机是java提供的一个伪随机数生成器。
生成“min <=随机数<= max”的随机数:
import java.util.Random;
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* @param min Minimum value
* @param max Maximum value. Must be greater than min.
* @return Integer between min and max, inclusive.
* @see java.util.Random#nextInt(int)
*/
public static int randInt(int min, int max) {
// NOTE: Usually this should be a field rather than a method
// variable so that it is not re-seeded every call.
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
方法三:标准库
在实际使用中,没有必要区重新写一次这些随机数的生成规则,可以借助一些标准库完成。如commons-lang。
org.apache.commons.lang3.RandomUtils提供了如下产生指定范围的随机数方法:
// 产生 start <= 随机数 < end 的随机整数
public static int nextInt(final int startInclusive, final int endExclusive);
// 产生 start <= 随机数 < end 的随机长整数
public static long nextLong(final long startInclusive, final long endExclusive);
// 产生 start <= 随机数 < end 的随机双精度数
public static double nextDouble(final double startInclusive, final double endInclusive);
// 产生 start <= 随机数 < end 的随机浮点数
org.apache.commons.lang3.RandomStringUtils提供了生成随机字符串的方法,简单介绍一下:
/ 生成指定个数的随机数字串
public static String randomNumeric(final int count);
// 生成指定个数的随机字母串
public static String randomAlphabetic(final int count);
// 生成指定个数的随机字母数字串
public static String randomAlphanumeric(final int count);
15.JavaBean到底是什么?
(我的理解:JavaBean是一个特殊的Java类,1.类是public类型的。2.属性都是private类型的。3.有一个无参的public构造方法。4.每个属性都要setter和getter方法。)
问题:按照我的理解: “Bean” 是一个带有属性和getters/setter方法的Java类。它是不是和C的结构体是相似的呢,对吗? 一个“Bean”类与普通的类相比是不是语法的不同呢?还是有特殊的定义和接口? 为什么会出现这个术语呢,这让我很困惑? 如果你很好心告诉我一些关于Serializable接口的信息,对于你的答案那到底是什么意思,我会非常感谢你的。
回答:
JavaBean 只是一个标准
就这些,它只是一个规范。但是很多的类库都是依赖于这些预定。
对于Serializable,看一下API文档的解释
实现java.io.Serializable接口的类能串行化。
不实现此接口的类不会有任何状态的序列化和反序列化。
可序列化类的所有子类型本身都是可序列化。
序列化接口没有方法或字段,仅用于标识的可序列化的语义。
换句话说,序列化的对象可以被写入流,文件,对象数据库等。
另外,一个JavaBean类和一个普通的类没有语法区别,如果遵循上面的标准的话,一个类可以认为成JavaBean类。
之所以需要JavaBean,是因为这样预定义了一种类的格式,一些库能依据这个约定的格式,来做一些自动化处理。举个例子,如果一个类库需要通过流来处理你传递的任何对象,它知道它可以正常处理,因为这个对象是可序列化的。(假设这个类库要求你的对象是JavaBeans)