public static void main(String[] args) {
Set s1 = new HashSet<>();
s1.add("one");
Set s2 = new HashSet<>();
s2.add(12);
int result = cacl(s1, s2);
System.out.println(result);
}
//不在乎Set集合元素的类型,但有需要类型安全
private static int cacl(Set> s1, Set> s2) {
int count = 0;
for (Object object : s2) {
if (s1.contains(object)) {
count++;
}
}
return count;
}
但有些例外,必须使用原始类型,一个就是类字面量
//合法
List.class, String[].class, and int.class
//不合法
List.class and List>.class
@SuppressWarnings("unchecked")
public T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
public class Chooser {
private final T[] choiceArray;
//参数类型都是T,是安全的
@SuppressWarnings("unchecked")
public Chooser(Collection choices) {
choiceArray = (T[]) choices.toArray();
}
// choose method unchanged}
下面使用泛型列表实现,虽然性能不及数组,但没有任何警告和错误,类型是安全的
public class Chooser {
private final List choiceList;
public Chooser(Collection choices) {
choiceList = new ArrayList<>(choices);
}
public T choose() {
Random rnd = ThreadLocalRandom.current();
return choiceList.get(rnd.nextInt(choiceList.size()));
}
}
public class Stack {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
//elements 是私有的,引用没有外泄,包含元素只有push方法的E,所以确定是类型安全的
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null;
return result;
}
}
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
//push时的元素只能是E,所以这里是类型安全的
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null;
return result;
}
}
PhoneNumber.java
public class PhoneNumber implements Comparable {
@Override
public int compareTo(PhoneNumber phoneNumber) {
int result = Short.compare(areaCode, phoneNumber.areaCode);
if (result == 0) {
result = Short.compare(prefix, phoneNumber.prefix);
if (result == 0) {
result = Short.compare(linNum, phoneNumber.linNum);
}
}
return result;
}
}
public class Test {
public static void main(String[] args) {
List integers=new ArrayList<>(10);
integers.add(2);
//print(integers);编译不通过
}
public static void print(List number){
System.out.println(number.toString());
}
}
public class Test {
public static void main(String[] args) {
List integers=new ArrayList<>(10);
integers.add(2);
print(integers);
}
//使用有限制的通配符类型
public static void print(List extends Number> number){
System.out.println(number.toString());
}
}
在Item 29我们有个泛型类Stack
public class Stack {
public Stack();
public void push(E e);
public E pop();
public boolean isEmpty();
}
如果我们添加一个方法addAll,按照之前的思路会是下面这个样子
public void pushAll(Iterable src) {
for (E e : src)
push(e);
}
public static void swap(List> list, int i, int j) {
swapHelper(list, i, j);
}
//使用私有的方法捕获通配符类型
private static void swapHelper(List list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}
总的来说使用通配符让API更加灵活,基本原则就是
生产者使用extends
消费者使用super,所有的comparables 和 comparators 都是消费者
Item 32 谨慎结合泛型和可变参数
可变参数可以极大的方便方法的调用,它允许给一个方法传递可变数量的参数,如下所示
public static void main(String[] args) {
show("one","two");
show("one","two","three");
}
public static void show(String... msgs) {
for (String string : msgs) {
System.out.println(string);
}
}
但这样你可能还不满足,参数String是具体类型,如果改成下面这样的泛型参数岂不更妙,
public static void main(String[] args) {
show("one","two");
show(1,3,4);
show(1.2f,3,4f);
}
public static void show(T... msgs) {
for (T string : msgs) {
System.out.println(string);
}
}
Arrays.java
@SafeVarargs
@SuppressWarnings("varargs")
public static List asList(T... a) {
//注意:此处ArrayList为Arrays的私有静态内部类
return new ArrayList<>(a);
}
Collections.java
@SafeVarargs
public static boolean addAll(Collection super T> c, T... elements) {
boolean result = false;
for (T element : elements)
result |= c.add(element);
return result;
}
EnumSet.java
@SafeVarargs
public static > EnumSet of(E first, E... rest) {
EnumSet result = noneOf(first.getDeclaringClass());
result.add(first);
for (E e : rest)
result.add(e);
return result;
}
public static void main(String[] args) {
//传人的参数编译时类型为String
String[] msg=toArray("one","two");
//为Integer
Integer[] integer=toArray(1,3,4);
}
//下面是反编译的字节码 参数类型都变成了Object,但做了正确的类型转换
invokestatic Method toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
checkcast class "[Ljava/lang/String;"
invokestatic Method toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
checkcast class "[Ljava/lang/Integer;"
如果上面这个可以使用,下面这个应该也没什么问题
public static void main(String[] args) {
String[] reuslt=pickTwo("t1", "t2");
}
static T[] pickTwo(T a, T b,) {
switch(ThreadLocalRandom.current().nextInt(3)) {
case 0: return toArray(a, b);
case 1: return toArray(a, c);
case 2: return toArray(b, c);
}
throw new AssertionError(); // Can't get here
}
//没有checkcast,返回的就是Object数组,实际类型信息丢失
invokestatic Method toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
invokestatic Method pickTwo(Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
checkcast class "[Ljava/lang/String;"
实际上编译的时候确实没有问题,但运行起来就会报错:ava.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; 因为此时toArray接受到的参数编译时类型为Object,所以返回的是Object数组,pickTwo接受到的也是Object数组,强转成String[]就报错。如果如下去除泛型,确定pickTwo的参数类型,也不会报错,只是没什么意义。
@SafeVarargs
static List flatten(List extends T>... lists) {
List result = new ArrayList<>();
for (List extends T> list : lists)
result.addAll(list);
return result;
}
public static void main(String[] args) {
List attributes = pickTwo("Good", "Fast", "Cheap");
}
static List pickTwo(T a, T b, T c) {
switch(rnd.nextInt(3)) {
case 0: return List.of(a, b);
case 1: return List.of(a, c);
case 2: return List.of(b, c);
}
throw new AssertionError();
}
//checkedList返回一个对ArrayList的包装类
List c=Collections.checkedList(new ArrayList<>(), String.class) ;
List d=c;
//添加失败
d.add(1);
//Collections.java
public static List checkedList(List list, Class type) {
return (list instanceof RandomAccess ?
new CheckedRandomAccessList<>(list, type) :
new CheckedList<>(list, type));
}
1 svn回退版本
1)在window中选择log,根据想要回退的内容,选择revert this version或revert chanages from this version
两者的区别:
revert this version:表示回退到当前版本(该版本后的版本全部作废)
revert chanages from this versio
<!--javascript取当月最后一天-->
<script language=javascript>
var current = new Date();
var year = current.getYear();
var month = current.getMonth();
showMonthLastDay(year, mont
public class MyStack {
private long[] arr;
private int top;
public MyStack() {
arr = new long[10];
top = -1;
}
public MyStack(int maxsize) {
arr = new long[maxsize];
top
Binary search needs an ordered array so that it can use array indexing to dramatically reduce the number of compares required for each search, using the classic and venerable binary search algori