当容器不使用泛型的时候,取出来是Object,需要转型成需要的类型
class Apple{
private static long counter;
private final long id = counter++;
public long id() { return id;}
}
public class Main{
public static void main(String[] args){
ArrayList apples = new ArrayList();
for(int i = 0; i < 3; i++){
apples.add(new Apple());
}
for(int i = 0; i < apples.size(); i++){
((Apple)apples.get(i)).id();
}
}
}
而使用了泛型后,就不需要去转型了
class Apple{
private static long counter;
private final long id = counter++;
public long id() { return id;}
}
public class Main{
public static void main(String[] args){
ArrayList<Apple> apples = new ArrayList<Apple>();
for(int i = 0; i < 3; i++){
apples.add(new Apple());
}
for(int i = 0; i < apples.size(); i++){
System.out.println(((Apple)apples.get(i)).id());
}
}
}
利用Arrays.adList()来生成容器
public class Main{
public static void main(String[] args){
List<Integer> list = Arrays.asList(1, 2, 3, 4);
//list.add(5); //error 固定了,不能再添加了
Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3,4));
collection.add(5); // 使用了ArrayList去包裹
}
}
关于使用Arrays.adList()的注意:
public class Main{
public static void main(String[] args){
Random rand = new Random(47);
Integer[] ia = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
System.out.println("Before shuffling: " + list1);
Collections.shuffle(list1, rand);
System.out.println("After shuffling: " + list1);
System.out.println("Array: " + Arrays.asList(ia));
List<Integer> list2 = Arrays.asList(ia);
System.out.println("Before shuffling: " + list2);
Collections.shuffle(list2, rand);
System.out.println("After shuffling: " + list2);
System.out.println("Array: " + Arrays.asList(ia));
}
}
运行结果:
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9]
Array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
Array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
使用ArrayList包装后,不会影响原始数组,反正则反
容器的打印
public class Main{
static Collection fill(Collection<String> collection){
collection.add("rat");
collection.add("cat");
collection.add("dog");
collection.add("dog");
return collection;
}
static Map fill(Map<String, String> map){
map.put("rat", "Fuzzy");
map.put("cat", "Rags");
map.put("dog", "Bosco");
map.put("dog", "Spot");
return map;
}
public static void main(String[] args){
System.out.println(fill(new ArrayList<String>()));
System.out.println(fill(new LinkedList<String>()));
System.out.println(fill(new HashSet<String>()));
System.out.println(fill(new TreeSet<String>()));
System.out.println(fill(new LinkedHashSet<String>()));
System.out.println(fill(new HashMap<String, String>()));
System.out.println(fill(new TreeMap<String, String>()));
System.out.println(fill(new LinkedHashMap<String, String>()));
}
}
运行结果:
[rat, cat, dog, dog]
[rat, cat, dog, dog]
[rat, cat, dog]
[cat, dog, rat]
[rat, cat, dog]
{rat=Fuzzy, cat=Rags, dog=Spot}
{cat=Rags, dog=Spot, rat=Fuzzy}
{rat=Fuzzy, cat=Rags, dog=Spot}
容器的迭代器
public class Main{
public static void main(String[] args){
List<Integer> list = new ArrayList<Integer>();
for(int i = 0; i < 5 ; i++){
list.add(i);
}
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.println(i);
}
}
}
使用迭代器有什么好处呢?
public class Main{
public static void display(Iterator<Integer> it){
while(it.hasNext()){
Integer i = it.next();
System.out.print(i+" ");
}
System.out.println();
}
public static void main(String[] args){
ArrayList<Integer> alist = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4));
LinkedList<Integer> llist = new LinkedList<Integer>(Arrays.asList(1, 2, 3, 4));
HashSet<Integer> hset = new HashSet<Integer>(Arrays.asList(1, 2, 3, 4));
TreeSet<Integer> tset = new TreeSet<Integer>(Arrays.asList(1, 2, 3, 4));
display(alist.iterator());
display(llist.iterator());
display(hset.iterator());
display(tset.iterator());
}
}
运行结果:
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
使用这种迭代器模式,不用去区分到底用的是哪种容器,能够将遍历序列的操作与序列底层的结构分离,可以说迭代器统一了堆容器的访问方式
SET
HashSet:使用散列函数实现的,所以必须存入实现了hashcode()的对象,并且可存入一个null值,元素无序,速度较快
TreeSet: 使用红黑树实现的,不能存入null值,因为是有序的,所以查找速度慢于HashSet
可参考: http://www.cnblogs.com/smiles125/p/5370204.html
Foreach与迭代器
如果创建的类实现了Iterable的类,都可以将它用于foreach的语句中,来看个例子:
class IterableClass implements Iterable<String>{
protected String[] words = ("And that is how we know the earth to be banana-shaped").split(" ");
public Iterator<String> iterator(){
return new Iterator<String>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < words.length;
}
@Override
public String next() {
return words[index++];
}
public void remove(){
throw new UnsupportedOperationException();
}
};
}
}
public class Main{
public static void main(String[] args){
for(String s : new IterableClass()){
System.out.print(s + " ");
}
}
}
运行结果:
And that is how we know the earth to be banana-shaped
如果想要在foreach中,进行不同遍历,应该如何实现了?可以通过添加一个能产生Iterable对象的方法,适配器方法惯用法
class ReversibleArrayList<T> extends ArrayList<T>{
public ReversibleArrayList(Collection<T> c){
super(c);
}
public Iterable<T> reversed(){
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
int current = size() - 1;
@Override
public boolean hasNext() {
return current > -1;
}
@Override
public T next() {
return get(current--);
}
public void remove(){
throw new UnsupportedOperationException();
}
};
}
};
}
}
public class Main{
public static void main(String[] args){
ReversibleArrayList<String> ral = new ReversibleArrayList<String>(Arrays.asList("To be or not to be".split(" ")));
// ArrayList 继承了Iterable
for(String s : ral){
System.out.print(s + " ");
}
System.out.println();
//利用内部类 来生成Iterable 对象
for(String s : ral.reversed()){
System.out.print(s + " ");
}
}
运行结果:
To be or not to be
be to not or be To
这里利用了内部类去实现,如果对内部类不太熟悉,可以参考一下:https://blog.csdn.net/qq_27469549/article/details/79861883