集合框架(List和Set)
一、概述
集合是一种可变数据项的容器,具有统一的父类接口Collection<E>
(Map
并没有继承之),与其子集合的关系例如以下 图。集合的特点是长度可变,能够存储多种类型的对象(不加泛型时)。这也是与数组的两点最大的不同。
java集合类关系图 |
Collection
最为根接口,List
、Set
、Queue
接口均直接继承自它,Map
接口尽管不是直接继承自Collection
,可是接口中使用到了Collection
,即Map的数据也是使用Collection
存储的。
研究集合不可缺少的是先研究Collection
接口的内容,先从接口名字定义開始说起public interface Collection<E> extends Iterable<E>
,这是集合的根接口。<E>
是JDK1.5開始的泛型,其功能是提高安全性,增强针对性,详细介绍后面再说。Iterable<E>
接口是迭代器。以下有详细介绍。
Collection
接口提供了一些集合的共性方法,如:
boolean add(E e)
加入一条数据。boolean addAll(Collection<?
加入还有一个集合内的元素。extends E> c)
void clear()
清除全部数据。boolean contains(Object o)
是否包括指定数据。Iterator<E> iterator()
返回迭代器。boolean remove(Object o)
删除指定数据。<T>T[] toArray(T[] a)
返回数据的数组形式等等。boolean retainAll(Collection<?> c)
取与集合c的交集。boolean removeAll(Collection<?> c)
取与集合c的差集。
二、迭代器
一种集合的取出方式,用于集合的数据的遍历等。
不同容器的数据结构不同,所以取出的动作实现不同,详细的取出动作定义在每一个容器的内部,这样取出方式就能够直接訪问集合内部元素。取出方式就被定义成了内部类。可是都有共性内容推断和取出,共性抽取便形成了Iterator
接口(迭代器)。
迭代器的使用演示样例(暂时不考虑泛型):
ArrayList alist = new ArrayList();
alist.add("java01");
alist.add("java02");
alist.add("java03");
alist.add("java04");
for(Iterator it = alist.iterator(); it.hasNext(); ) {
System.out.println(it.next());
}
三、List
List
为Collection的常见子接口之中的一个,元素有序。能够反复,有索引。
List
有些特有的方法,和下标相关的一些方法。如:
- 增:add(index, element)
指定位置加入元素,addAll(index, Collection)
指定位置加入一个集合的元素。
- 删:remove(index)
删除指定为的元素。
- 改:set(index, element)
改动指定位置的元素。
- 查:get(index)
获取指定位置的元素。subList(from, to)
获取[from, to)
段的子List
,listIterator()
获取List
特有的迭代器,indexOf(E)
获取对象的位置。
ListIterator
ListIterator
是Iterator
的子接口,在迭代时不能够通过集合的操作对集合进行操作,会发生并发改动异常,可是Iterator
的操作是有限的,假设想对元素进行加入和改动等,就须要用到其子接口ListIterator
,该接口仅仅能通过List
的listIterator()
方法获取,演示样例代码例如以下:
ArrayList alist = new ArrayList();
alist.add("java01");
alist.add("java02");
alist.add("java03");
alist.add("java04");
for(ListIterator it = alist.listIterator(); it.hasNext(); ) {
System.out.println(it.next());
it.add("java");
}
System.out.println(alist);
//输出结果是
java01
java02
java03
java04
[java01, java, java02, java, java03, java, java04, java]
通过上面能够看到,ListIterator
在获取之后其遍历的内容就已经确定下来了。 ListIterator
还有逆向遍历功能。
ArrayList alist = new ArrayList();
alist.add("java01");
alist.add("java02");
alist.add("java03");
alist.add("java04");
ListIterator it = alist.listIterator();
while(it.hasNext()) {
System.out.println(it.next());
}
while(it.hasPrevious()) {
System.out.println(it.previous());
}
// 输出的结果是
java01
java02
java03
java04
java04
java03
java02
java01
List
中详细对象特点
List
有三个详细的子类,各自是ArrayList
、LinkedList
和Vector
。
三者的特点与不同例如以下:
ArrayList
:底层数据结构为数组结构,线程非同步。查询速度快,增删速度慢,效率比Vector
高,最早出如今JDK1.2版本号。初始长度默觉得10。空间不足时50%延长。LinkedList
:底层数据结构为链表结构,线程非同步,查询速度慢,增删速度快,最早出如今JDK1.2版本号。Vector
:底层数据结构是数组结构,线程同步,与ArrayList
有同样的功能。已被ArrayList
取代,最早出如今JDK1.0版本号。默认长度为10,空间不足时100%延长。
Vector
的特点
Vector
的特有的一点就是,Vector
的枚举(Vector
的特有取出方式),和迭代器相似,名为Enumeration
,ArrayList
中没有此功能。可是由于方法名过长,且没有移除功能,已被Iterator
取代,所以一般优先考虑使用Iterator
。演示样例代码例如以下:
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
Enumeration en = v.elements();
while(en.hasMoreElements()) {
System.out.println(en.nextElement());
}
// 输出结果为
java01
java02
java03
LinkedList
LinkedList
的特有方法:addFirst(E e)
、addLast(E e)
加入到头部或者尾部、getFirst()
、getLast()
获取头部元素或者尾部元素、removeFirst()
、removeLast()
删除头部元素或者尾部元素,并返回删除的元素,没有会报NoSuchElementException
,这些是LinkedList
所特有的方法。JDK1.6版本号名称发生了变化,分别变成了offerFirst(E e)
,offerLast(E e)
,peekFirst()
,peekLast()
。pollFirst()
。pollLast()
。没有会返回null
。
LinkedList
练习,模拟队列进行加入和取出动作。演示样例代码例如以下:
import java.util.*;
class MyQueue {
private LinkedList link;
MyQueue() {
link = new LinkedList();
}
public void myAdd(Object obj) {
link.addFirst(obj);
}
public Object myGet() {
return link.removeFirst();
}
public boolean isNull() {
return link.isEmpty();
}
}
class LinkedListTest {
public static void main(String[] args) {
MyQueue q = new MyQueue();
q.myAdd("java01");
q.myAdd("java02");
q.myAdd("java03");
q.myAdd("java04");
while(!q.isNull()) {
System.out.println(q.myGet());
}
}
}
ArrayList
ArrayList
练习,去除ArrayList
中的反复项。
代码示比例如以下:
import java.util.*;
class ArrayListTest {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("java01");
list.add("java02");
list.add("java01");
list.add("java02");
list.add("java01");
list.add("java03");
// 去除反复前
System.out.println(list);
list = singleElement(list);
// 去除反复后
System.out.println(list);
}
public static ArrayList singleElement(ArrayList list) {
//定义一个暂时容器。
ArrayList newList = new ArrayList();
// 获取迭代器
Iterator it = list.iterator();
while(it.hasNext()) {
Object obj = it.next();
if(!newList.contains(obj)) {
newList.add(obj);
}
}
return newList;
}
}
ArrayList
练习。自己定义类加入至ArrayList
,须要覆盖自己定义类的equals
方法。
import java.util.*;
class Person {
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 覆盖equals方法
public boolean equals(Object obj) {
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String toString() {
return "Name:" + this.name + " Age:" + this.age;
}
}
class ArrayListTest {
public static void main(String[] args) {
ArrayList list= new ArrayList();
list.add(new Person("lisi01",30));
list.add(new Person("lisi02",32));
list.add(new Person("lisi02",32));
list.add(new Person("lisi04",35));
list.add(new Person("lisi03",33));
list.add(new Person("lisi04",35));
System.out.println(list);
list = singleElement(list);
System.out.println(list);
}
public static ArrayList singleElement(ArrayList al) {
// 定义一个暂时容器。
ArrayList newList = new ArrayList();
// 取出迭代器
Iterator it = al.iterator();
while(it.hasNext()) {
Object obj = it.next();
if(!newList.contains(obj))
newList.add(obj);
}
return newList;
}
}
四、Set
元素无序(存入与取出的顺序不一致),元素不可反复。
有两个主要子类:HashSet
和TreeSet
。
HashSet
:底层数据结构为哈希表。TreeSet
:底层数据结构为二叉树。
HashSet
依据hashCode()
和equals()
方法进行存储。add
时。假设是第一次加入返回true
(加入成功),否则返回false
(加入失败)。演示样例代码例如以下:
import java.util.*;
class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
// 第一次加入java01返回true
System.out.println(hs.add("java01"));
// 第二次加入java01返回false
System.out.println(hs.add("java01"));
hs.add("java02");
hs.add("java03");
hs.add("java03");
hs.add("java04");
// 遍历集合
Iterator it = hs.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
HashSet
存储自己定义对象,自己定义对象须要覆盖hashCode
和equals
方法。当hashCode
值同样、equals
返回真时,觉得是同一个对象。加入时。当hashCode
值不同一时候,不会调用equals
比較,当hashCode
的值同样时,才会调用equals
方法比較两个对象。
演示样例代码例如以下:
import java.util.*;
/**
*姓名和年龄同样觉得是同一个人
*/
class Person {
private String name;
private int age;
Person(String name,int age) {
this.name = name;
this.age = age;
}
public int hashCode() {
System.out.println(this.name+"....hashCode");
return name.hashCode() + age*37;
}
public boolean equals(Object obj) {
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
// 加入一个同样的人
hs.add(new Person("a2",12));
hs.add(new Person("a4",14));
// 遍历集合中的人
Iterator it = hs.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.getName()+"::"+p.getAge());
}
}
}
// 执行结果为
a1....hashCode
a2....hashCode
a3....hashCode
a2....hashCode
a2...equals..a2
a4....hashCode
a3::13
a1::11
a4::14
a2::12
从上面代码执行的结果能够看出,当加入new Person("a2",12)
时。由于集合中已经有这个人了。所以hashCode
的返回值已经存在。因此便会调用equals方法推断,终于结果还是此人已存在,所以最总集合中仅仅有4个人。
HashSet的推断和删除依据,能够看到判读元素是否存在和删除元素都是首先依据hashCode
值,然后再通过equals
推断是否同样。
import java.util.*;
/**
*姓名和年龄同样觉得是同一个人
*/
class Person {
private String name;
private int age;
Person(String name,int age) {
this.name = name;
this.age = age;
}
/**
*统一返回1作为哈希值
*/
public int hashCode() {
System.out.println("hashCode");
return 1;
}
/**
* 姓名和年龄同样觉得是同一个人
*/
public boolean equals(Object obj) {
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
// 加入一个同样的人
hs.add(new Person("a2",12));
hs.add(new Person("a4",14));
System.out.println("--------");
// 推断是否存在元素
hs.contains(new Person("a4", 14));
System.out.println("--------");
// 删除指定元素
hs.remove(new Person("a1", 11));
}
}
// 执行结果为
hashCode
hashCode
a2...equals..a1
hashCode
a3...equals..a1
a3...equals..a2
hashCode
a2...equals..a1
a2...equals..a2
hashCode
a4...equals..a1
a4...equals..a2
a4...equals..a3
--------
hashCode
a4...equals..a1
a4...equals..a2
a4...equals..a3
a4...equals..a4
--------
hashCode
a1...equals..a1
TreeSet
能够对集合中的元素进行排序。
底层数据结构为二叉树。中序遍历便是TreeSet
的顺序。
演示样例代码例如以下:
import java.util.*;
class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add("asdas");
ts.add("abc");
ts.add("beds");
ts.add("abd");
Iterator it = ts.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
// 执行结果为
abc
abd
asdas
beds
对于自己定义对象的排序,一般有两种做法,一是自己定义对象自己实现Comparable
接口。二是集合提供比較器(Comparator
接口)。
自己定义对象实现Comparable
接口,演示样例代码例如以下:
import java.util.*;
class Student implements Comparable {
private String name;
private int age;
Student(String name,int age) {
this.name = name;
this.age = age;
}
/**
*比較结果又三种。负数表示小于,0表示等于,正数表示大于
*/
public int compareTo(Object obj) {
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age) {
// String类已经实现了Comparable接口
return this.name.compareTo(s.name);
}
return -1;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi08",19));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi01",40));
// 遍历集合
Iterator it = ts.iterator();
while(it.hasNext()) {
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
集合提供比較器(Comparator
接口)的比較方式。用于元素不具备比較性或者具备的比較性不是用户所须要的时。演示样例代码例如以下:
import java.util.*;
class Student implements Comparable {
private String name;
private int age;
Student(String name,int age) {
this.name = name;
this.age = age;
}
/**
*比較结果又三种,负数表示小于,0表示等于,正数表示大于
*/
public int compareTo(Object obj) {
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age) {
return this.name.compareTo(s.name);
}
return -1;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new MyCompare());
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",21));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi007",29));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi01",40));
Iterator it = ts.iterator();
while(it.hasNext()) {
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
class MyCompare implements Comparator {
public int compare(Object o1,Object o2) {
Student s1 = (Student)o1;
Student s2 = (Student)o2;
// 姓名比較优先
int num = s1.getName().compareTo(s2.getName());
if(num==0) {
// 姓名同样时,年龄小的在前
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
五、泛型
泛型的出现攻克了类型不同的安全问题,JDK1.5版本号開始出现的。详细做法就是在集合定义时指明数据类型。如ArrayList<String> list= new ArrayList<String>()
,这样一来假设向list
中加入非String
类型对象时。就会在编译时期提示ClassCastException
异常。演示样例代码例如以下:
import java.util.*;
class GenericDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("abc01");
list.add("abc0991");
list.add("abc014");
// Iterator也有相应的泛型
Iterator<String> it = al.iterator();
while(it.hasNext()) {
System.out.println(s+":"+s.length());
}
}
}
自己定义类中使用泛型的概念。试用于用数据类型不确定时,演示样例代码例如以下:
class Worker {
}
class Student {
}
/**
*泛型类,使用与引用数据类型不确定时。
*/
class Utils<Q> {
private Q q;
public void setObject(Q q) {
this.q = q;
}
public Q getObject() {
return q;
}
}
class GenericDemo3 {
public static void main(String[] args) {
Utils<Worker> u = new Utils<Worker>();
u.setObject(new Worker());
Worker w = u.getObject();;
}
}
泛型定义在方法上,演示样例代码例如以下:
class Demo {
public <T> void show(T t) {
System.out.println("show:"+t);
}
public <Q> void print(Q q) {
System.out.println("print:"+q);
}
/**
* 静态方法不能够訪问类上的泛型。可使用静态泛型方法。注意:泛型标识<E>需放在返回值前。
*/
public static <E> void printf(E e) {
System.out.println("printf:"+e);
}
}
class GenericDemo4 {
public static void main(String[] args) {
Demo demo = new Demo();
demo.show("Hi");
demo.print("Hello");
Demo.printf(5);
}
}
//执行结果为
show:Hi
print:Hello
show:5
泛型限定
一般有三种情况。
<?
:?为通配符。>
<? extends E>
:E和E的子类。称为上限。<? super E>
:E和E的父类。称为下限。
如对全部类型的ArrayList
进行遍历输出,演示样例代码例如以下:
public static void print(ArrayList<?> list) {
Iterator<?> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
}
对Person
或者Person
的子类Student
进行遍历并输出,演示样例代码例如以下:
public static void print(ArrayList<? extends Person> list) {
Iterator<? extends Person> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next().getName());
}
}
对于<?
super E>并不经常使用。举一个TreeSet里的样例,TreeSet(Comparator<?
super E> comparator),使用父类的比較器进行子类的比較。演示样例代码例如以下:
import java.util.*;
class Person {
private String name;
Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return "Person :"+name;
}
}
class Student extends Person {
Student(String name) {
super(name);
}
}
class Worker extends Person {
Worker(String name) {
super(name);
}
}
/**
* 定义使用与Person的比較器
*/
class Comp implements Comparator<Person> {
public int compare(Person p1,Person p2) {
// 倒序
return p2.getName().compareTo(p1.getName());
}
}
class GenericDemo {
public static void main(String[] args) {
// 使用使用父类的比較器进行比較
TreeSet<Student> ts = new TreeSet<Student>(new Comp());
ts.add(new Student("abc03"));
ts.add(new Student("abc02"));
ts.add(new Student("abc06"));
ts.add(new Student("abc01"));
Iterator<Student> it = ts.iterator();
while(it.hasNext()) {
System.out.println(it.next().getName());
}
// 使用使用父类的比較器进行比較
TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());
ts1.add(new Worker("wabc--03"));
ts1.add(new Worker("wabc--02"));
ts1.add(new Worker("wabc--06"));
ts1.add(new Worker("wabc--01"));
Iterator<Worker> it1 = ts1.iterator();
while(it1.hasNext()) {
System.out.println(it1.next().getName());
}
}
}
// 执行结果为
abc06
abc03
abc02
abc01
wabc--06
wabc--03
wabc--02
wabc--01
集合框架(List和Set)的更多相关文章
- 一起学 Java(三) 集合框架、数据结构、泛型
一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...
- 【目录】JUC集合框架目录
JUC集合框架的目录整理如下: 1. [JUC]JUC集合框架综述 2. [JUC]JDK1.8源码分析之ConcurrentHashMap(一) 3. [JUC]JDK1.8源码分析之Concurr ...
- java面试题——集合框架
先来看一下集合框架关系图 Collection FrameWork 如下: Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └S ...
- Java使用实现面向对象编程:第七章集合框架的解读=>重中之重
对于集合框架,是非常重要的知识,是程序员必须要知道的知识点. 但是我们为什么要引入集合框架呢? 我们之前用过数组存储数据,但是采用数组存储存在了很多的缺陷.而现在我们引用了集合框架,可以完全弥补了数组 ...
- Java集合框架List,Map,Set等全面介绍
Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I] +--java.util.ArrayList [C] +- ...
- Java集合框架练习-计算表达式的值
最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...
- Java 之 集合框架(JCF)
1.集合框架 a.框架:为了实现某一目的或功能,而预先提供的一系列封装好的.具有继承或实现关系的类与集合 b.集合:①定义:Java中对一些数据结构和算法进行封装,即封装(集合也是一种对象) ②特点: ...
- 【集合框架】Java集合框架综述
一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...
- 【集合框架】JDK1.8源码分析之Comparable && Comparator(九)
一.前言 在Java集合框架里面,各种集合的操作很大程度上都离不开Comparable和Comparator,虽然它们与集合没有显示的关系,但是它们只有在集合里面的时候才能发挥最大的威力.下面是开始我 ...
- 【集合框架】JDK1.8源码分析之Collections && Arrays(十)
一.前言 整个集合框架的常用类我们已经分析完成了,但是还有两个工具类我们还没有进行分析.可以说,这两个工具类对于我们操作集合时相当有用,下面进行分析. 二.Collections源码分析 2.1 类的 ...
随机推荐
- 【codeforces 749D】Leaving Auction
[题目链接]:http://codeforces.com/problemset/problem/749/D [题意] 有n个人在竞价; 按照时间的顺序给出n次竞价(可能有一些人没有参加竞价); 每次竞 ...
- NYIST 1070 诡异的电梯【Ⅰ】
诡异的电梯[Ⅰ]时间限制:1000 ms | 内存限制:65535 KB难度:3 描述新的宿舍楼有 N(1≤N≤100000) 层 and M(1≤M≤100000)个学生. 在新的宿舍楼里, 为了节 ...
- CodeForces 362E Petya and Pipes
Petya and Pipes Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. ...
- nutch如何修改regex-urlfilter.txt爬取符合条件的链接
例如我在爬取学生在线的时候,发现爬取不到特定的通知,例如<中粮福临门助学基金申请公告>,通过分析发现原来通知的链接被过滤掉了,下面对过滤url的配置文件regex-urlfilter.tx ...
- ACCESS-入门思维导图
ACCESS-入门思维导图 链接:http://pan.baidu.com/s/1bozYiNt 密码:5tly 如果有错误,请告知我!
- SQL SERVER-in,between,like
and 1 LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式 ( 可以使用正则表达式) select * from [User] where UserName like '%r' -- 以 ...
- java应届生面试考点收集
回 到 顶 部 这些知识点来自于之前去百度实习.阿里.蘑菇街校园招聘的电话面试 未完待续 JavaSE 面向对象 封装.继承.多态(包括重载.重写) 常见区别 String.StringBuffer. ...
- HTML5简单进度环插件
前几天做了一个进度条的插件.今天我用HTML5的arc做一个简单的进度环的插件. 代码演示 事实上非常easy的.相同,我们先用一个实例: 配置js代码 var setting = { id: &qu ...
- ruby on rails错误undefined method `title' for nil:NilClass
首先搞清楚这句话,在 Ruby 中,方法分为 public.private 和 protected 三种,仅仅有 public 方法才干作为控制器的动作. 我的出错的代码例如以下: controlle ...
- 在fragment中显示对话框出现异常
异常类型为:android.view.WindowManager$BadTokenException: Unable to add window 我在fragment中public View onCr ...