持有对象

链表

  • arrayList:随机访问性能好,插入和删除效率差
  • LinkedList:插入和删除效率高,随机访问性能差

初始化

// 1.使用 Arrays.asList 将数组转化为容器进行初始化,速度最慢
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(1,2,3));
// 2.使用 Collection.addAll() 进行初始化,速度比第一种方案快,但是只能接受容器作为参数
List<Integer> list2 = new ArrayList<Integer>();
list2.addAll(list1);
// 3. 使用 Collections.addAll() 进行初始化,速度最快且参数灵活,首选方案
List<Integer> list3 = new ArrayList<Integer>();
Collections.addAll(list3,1,2,3);
// Array.asList() 与 Collections.addAll() 都是可变参数列表,但是他们有一些区别
List<Snow> snow1 = Arrays.asList(new Powder(),new Crusty(),new Slush());
// 这样创建编译器会报错, 方法无法得到要创建的链表的类型信息
//List<Snow> snow2 = Arrays.asList(new Powder(),new Light(),new Heavy());
List<Snow> snow3 = new ArrayList<Snow>();
// 方法从第一个参数获取类型信息
Collections.addAll(snow3,new Powder(),new Crusty(),new Slush());

class Snow {}
class Powder extends Snow {}
class Light extends Powder {}
class Heavy extends Powder {}
class Crusty extends Snow {}
class Slush extends Snow {}

打印

// 对于数组打印需要使用 Array.toString() 但是容器可以直接打印
System.out.println(Arrays.toString(new Integer[]{1,2,3}));
System.out.println(list1);

链表常用方法

ArrayList<String> arrayList = new ArrayList<String>();
arrayList.isEmpty();
arrayList.contains("red");
arrayList.containsAll(Arrays.asList("red","black"));
arrayList.addAll(Arrays.asList("red","blue","green","white","yellow","grey"));
arrayList.add("black");
//在当前位置插入即 2
arrayList.add(2,"pink");
arrayList.get(2);
arrayList.set(2,"red");
arrayList.remove(4);
//删除出现的第一个
arrayList.remove("red");
arrayList.add("red");
arrayList.add("red");
// 遍历,所有的都删除
arrayList.removeAll(Arrays.asList("red","blue"));
arrayList.indexOf("red");
arrayList.lastIndexOf("red");
List<String> subList = arrayList.subList(1,3);
System.out.println(subList);
System.out.println(subList.indexOf("yellow"));
// 对 subList 的修改会作用到原链表
subList.add("golden");
System.out.println(arrayList);
subList.clear();
System.out.println(arrayList);

LinkedList 除了与 ArrayList 提供的链表常用的方法之外,还提供了对栈,队列,以及双端队列的支持。所以 LinkedList 的方法比 ArrayList 丰富,并且将 LinkedList 向上转型为 List 时,这些这栈,队列,双端队列支持的方法也将不能使用。

队列

Queue 接口 继承了 Collection 接口,并在 COllection 接口的基础上扩展了对容器元素的插入,提取,以及检查操作。每种操作都提供了两种不同的方法,当相应的操作失败时,一种抛出异常而另一种返回一个特殊值(null 或者 false)。插入失败的接口设计针对的是容量大小有限制的队列,一般情况下不会失败。

抛出异常返回特殊值
add(e)offer(e)
remove()poll()
element()peek()

在队列的使用中,不应该插入 null 值,尽管它的实现 LinkedList 允许插入,但是也不应该这样做,应为队列 poll() 使用 null 作为队列为空的标志。

双端队列(double ended queue)

抛出异常返回特殊值
addFirst(e)/addLast(e)offerFirst(e)/offerLast(e)
removeFirst()/removeLast()pollFirst()/pollLast()
getFirst()/getLast()peekFirst()/peekLast()

queue和deque 方法对比

queuedeque
add(e)addFirst(e)
offer(e)offerFirst(e)
remove()removeFirst()
poll()pollFirst()
element()getFirst()
peek()peekFirst()

双端队列的接口设计时提供了对栈的支持,即可以将双端队列作为栈来操作。而这种用法要优于旧的 Stack 类。

stackdeque
push(e)addFirst(e)
pop()removeFirst()
peek()peekFirst()

优先队列

在优先队列上调用 offer() 方法插入对象时,这个对象在队列内会被排序。自己定义的类需要实现 comparable 或者提供自动的比较器。

Set

  • HashSet
  • TreeSet
  • LinkedHashSet

Map

  • HashMap
  • TreeMap
  • LinkedHashMap

Collection,Iterator,Iterable

  • Collection 和 Iterator 提供了面向接口而不是具体实现的编程方式。除 Map 以外其他的容器都实现了Collection 接口,而所有的 Collection 都有一个返回 Iterator 的方法。
public static <T> void display(Collection<T> collection){
    for(T obj : collection){
        System.out.print(obj + " ");
    }
    System.out.println();
}
public static <T> void display(Iterator<T> iterator){
    while(iterator.hasNext()){
        T obj = iterator.next();
        System.out.print(obj + " ");
    }
    System.out.println();
}

public static void main(String[] args){
    String[] array = new String[]{"red","blue","black","red"};
    List<String> linkedList = new LinkedList<String>(Arrays.asList(array));
    Set<String> hashSet = new HashSet<String>(Arrays.asList(array));
    CollectionTest.display(linkedList);
    CollectionTest.display(hashSet);
    CollectionTest.display(linkedList.iterator());
    CollectionTest.display(hashSet.iterator());
}
  • Map 通过 keySet(),values() 可以返回 COllection ,从而与 Collection 建立联系。

  • Collection 可以直接使用 foreach 语法,但是 Iterator 不能。但是两者各有优缺点。Collection 接口可以通过继承 AbstractColleciton 类因此有多继承的限制,而使用 Iterator 只需要在类定义一个返回该接口实例的方法。

public class MyCollection extends AbstractCollection<String> {
    private String[] array;

    public MyCollection(){
        super();
        array = new String[]{"red","blue","black"};
    }

    public Iterator<String> iterator() {
        return new Iterator<String>() {
            private int index = 0;
            public boolean hasNext() {
                return index < size();
            }

            public String next() {
                return array[index++];
            }
        };
    }

    public int size() {
        return array.length;
    }

    public static void main(String[] args){
        MyCollection myCollection = new MyCollection();
        CollectionTest.display(myCollection);
    }
}
public class MyCollection {
    private String[] array;

    public MyCollection(){
        super();
        array = new String[]{"red","blue","black"};
    }

    public Iterator<String> iterator() {
        return new Iterator<String>() {
            private int index = 0;
            public boolean hasNext() {
                return index < size();
            }

            public String next() {
                return array[index++];
            }
        };
    }

    public int size() {
        return array.length;
    }

    public static void main(String[] args){
        MyCollection myCollection = new MyCollection();
        CollectionTest.display(myCollection.iterator());
    }
}
  • Iterable 是 Java SE5 之后添加的新接口,任何实现该接口的类都可以使用 foreach 语句,Colleciton 接口继承了 Iterable 接口。但是数组虽然可以使用 foreach,但是数组并没有实现 Iterable 接口。
public class MyCollection implements Iterable<String> {
    private String[] array;

    public MyCollection(){
        super();
        array = new String[]{"red","blue","black"};
    }

    public Iterator<String> iterator() {
        return new Iterator<String>() {
            private int index = 0;
            public boolean hasNext() {
                return index < size();
            }

            public String next() {
                return array[index++];
            }
        };
    }

    public int size() {
        return array.length;
    }

    public static void main(String[] args){
        MyCollection myCollection = new MyCollection();
        for(String color : myCollection){
            System.out.print(color + " ");
        }
    }
}
  • 使用适配器模式显式的调用 foreach 语法。

通过上面的例子可以知道,当需要支持 foreach 语法时可以实现 Iterable 接口。但是假设我们希望有多个不同方式来进行迭代,这时可以采用适配器模式。

public Iterable<String> reversed(){
    return new Iterable<String>() {
        public Iterator<String> iterator() {
            return new Iterator<String>() {
            private int i = size();
                public boolean hasNext() {
                    return i > 0;
                }
                public String next() {
                    return array[--i];
                }
            };
        }
    };
}

MyCollection myCollection = new MyCollection();
for(String color : myCollection){
    System.out.print(color + " ");
}
System.out.println();
for(String color : myCollection.reversed()){
    System.out.print(color + " ");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值