1、字符串相关
String s1 = “abc”;//s1是一个类类型变量,所以要指向一个对象-”abc”
字符串最大特点:一旦被初始化,就不可以被改变。这里指的是该字符串对象值不可以被改变,而s1这个引用变量可以变。
String s2 = new String(“abc”);
这两句的区别?
s1在内存中有一个对象,s2在内存中有两个对象(new、”abc”)。
方法区在内存中包含:非静态方法区、静态区、常量池
StringBuffer与StringBuilder区别?
StringBuffer:保证同步(线程安全),多个线程使用同一个容器,读写也都能保证安全。
StringBuilder:JDK1.5提供的,不保证线程同步。单线程时,建议使用StringBuilder,效率高。
2、基本数据类型对象包装类
最常见作用:用于基本数据类型和字符串类型之间做转换。
JDK1.5版本新特性:
Integer x = 4;
右边的4也是对象,这一步进行了自动装箱(new Integer(4))。
x = x + 2;
自动拆箱。变成了int类型,和2进行加法运算。再将得到的结果进行装箱,赋给x
但,新特性里,x的值也可能为null,所以在使用前要进行是否为空判断。
一个例子:
Integer m = 128;
Integer n = 128;
Integer a = 127;
Integer b = 127;
System.out.println(m == n); //false①
System.out.println(a == b); //true②
①②因为a和b指向同一个Integer对象。因为当数值在byte范围内时,对于新特性,如果该数值已经存在,则不会再为其开辟新空间。byte范围:-128~127。而m和n已经超出了这个范围,所以分别指向的是两个对象。
2、集合
组织结构图:
Collection(根接口)
|--List(元素是有序的,可以重复,因为该集合有索引)
|--ArrayList(底层的数据结构使用的是数组结构,默认长度为10,后续延长为50%,10-15,特点:查询速度快,但增删较慢,线程不同步)
|--LinkedList(底层使用的是链表数据结构,特点:增删快,查询稍慢)
|--Vector(底层是数组结构,10-20,线程同步,被ArrayList替代了)
|--…
|--Set(元素是无序的,不可以重复)
|--HashSet
|--TreeSet
|--…
Collection、List、ArrayList、Set等。
1)Collection常用方法:
boolean add(E e):参数类型E是Object,以便于接收任意类型的对象。
boolean isEmpty():如果此 collection 不包含元素,则返回 true。
int size():返回此 collection 中的元素数。如果此 collection 包含的元素大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。
boolean contains(Object o):如果此 collection 包含指定的元素,则返回 true。(前提,集合和o都不能为null)。更确切地讲,当且仅当此列表包含至少一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,则返回 true。所以说,LIst集合判断元素是否相同,依据的是元素的equals()方法(而且,底层调用equals时,是o调用的)。
Iterator<E> iterator():返回在此 collection 的元素上进行迭代的迭代器。关于元素返回的顺序没有任何保证(除非此 collection 是某个能提供保证顺序的类实例)。
Object[] toArray():返回包含此 collection 中所有元素的数组。
<T> T[] toArray(T[] a)返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。如果指定的数组能容纳该 collection,则返回包含此 collection 元素的数组。否则,将分配一个具有指定数组的运行时类型和此 collection 大小的新数组。
boolean remove(Object o)从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。更确切地讲,如果此 collection 包含一个或多个满足 (o==null ? e==null : o.equals(e)) 的元素 e,则移除这样的元素。如果此 collection 包含指定的元素(或者此 collection 由于调用而发生更改),则返回 true 。
boolean containsAll(Collection<?> c)如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean addAll(Collection<? extends E> c):将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
boolean removeAll(Collection<?> c):移除与c集合的交集元素。
boolean retainAll(Collection<?> c):保留两个集合中的交集元素
void clear():清空该集合。
此处注意的是:ArrayList和LinkedList的contains()和remove()方法底层都调用了元素的equals方法。
2)集合中存储的都是对象的引用(地址)
集合类实现了Iterator(迭代器)的接口,要返回集合的元素,可以用下面的方式:
Iterator it = arrayList.iterator();
while(it.hasNext())
{
System.out.println(it.next()); //next()取一次,就要hasNext()判断一次
}
或者:
for(Iterator it = arrayList.iterator(); it.hasNext(); )
{
System.out.println(it.next());
}
第二种方式比较节省内存空间,因为Iterator对象使用完之后,资源就被释放了。
3)List(Collection的第一大派系)的特有方法:
增:add(index,element): //在角标index位置插入element元素
add(index,Collection);
删:remove(index); //删除index角标位置的元素,并返回该元素
改:set(index,element); //把index角标位置的元素改为element
查:get(index);获取index角标位置的元素
subList(from,to):返回从from(包含)到to(不包含)位置的子集合
listIterator();见下面。
indexOf(Object o):返回改对象在集合中的位置。
Iterator的方法:
E next();返回下一个元素
boolean hasNext();是否还有下一个
void remove();删除当前元素引用在集合中的位置,但该对象仍然存在
比如:
Iterator it = arrayList.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(obj.equals(“java”))
obj.remove(); //若存在”java”,则将其删除。
}
ListIterator是List集合特有的迭代器。ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常。
所以,在迭代器时,只能用迭代器的方法(Iterator的remove())操作元素,可是Iterator方法是有限的,只能对元素进行判断、取出、删除的操作。
如果想要其他的操作比如添加,修改等,就需要使用其子接口:ListIterator
该接口只能通过List集合的listIterator()方法获取。
ListIterator li = arrayList.listIterator();
while(it.hasNext())
{
Object obj = it.next();
if(obj.equals(“java”))
// li.add(“java01”);在”java”后面插入新元素
li.set(“java02”);// 修改当前元素为”java02”
}
该类的方法:
void add(E e) 将指定的元素插入列表
boolean hasNext() 如果有下一个元素,返回 true
boolean hasPrevious() 以逆向遍历列表,是否前面位置还有元素。
E next() 返回列表中的下一个元素。
int nextIndex() 返回后一个元素的索引。
E previous() 返回列表中的前一个元素。
int previousIndex() 返回前一个元素的索引。
void remove() 从列表中移除遍历到的当前位置的元素(可选操作)。
void set(E e) 用指定元素e替换遍历到的当前位置的元素(可选操作)。
Vector特点:支持枚举(Enumeration)。
ArrayList:没有。
Enumeration:枚举类
它是Vector特有的取出方式:
它有两个方法:hasMoreElement()、nextElement()。
看起来它和Iterator(迭代器)很像。因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。
LinkedList(链表结构的集合)特有方法:(面试)
①addFirst(); //在相应位置插入元素
②addLast();
③getFirst(); //获取相应位置的元素,但不删除
④getLast();
⑤removeFirst(); //获取相应元素,并删除
⑥removeLast();
//③~⑥方法如果要获取的位置没有元素,则抛出NoSuchElementException
⑦public E pollFirst():获取并删除相应元素,若列表为空则返回null
⑧public E pollLast()
⑨public E peekFirst():获取相应元素但不删除,为空返回null
⑩public E peekLast()
11)public boolean offerFirst(E e)在首/尾插入元素
12)public boolean offerLast(E e)
后面六个是JDK1.6才出现的,替代了前面六个。⑦~⑩方法不会抛异常。
另外,前面也提到过,它的contains和remove方法,底层都调用了元素的equals方法。
4)Set(Collection的第二大派系):
元素是无序的,存入和取出的顺序不一定一致,元素不可以重复。
其功能和Collection是一致的。
Set
|--HashSet:底层数据结构是哈希表。元素不可重复。线程不同步。
|--TreeSet:对集合中的元素按照自然顺序排序存入。底层数据结构是二叉树。
①HashSet是如何保证元素的唯一性的呢?
是通过元素的两个方法:hashCode和equals来完成。
如果元素的hashCode值相同,才会判断equals是否为true;
如果元素的hashCode值不同,不会调用equals。
比如add、contains、remove方法,都在底层调用了相应对象的这两个方法。
(而ArrayList集合,判断元素是否相同,只依赖equals方法。)
②TreeSet:
将元素按照自然顺序存入。底层数据结构是二叉树。
保证元素唯一性的依据是:compareTo方法。
TreeSet排序的第一种方式:
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也是元素的自然顺序,或者叫默认顺序。
TreeSet第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式——定义一个类,实现Comparator接口,覆盖compare方法,并将其对象作为参数传给TreeSet构造方法。
需要注意的是:当两种排序都存在时,以比较器为主。