基本数据单位
在java中数据由基本数据类型表达,然后存放在数据结构中。java的基本类型由string,char,byte,int,float,double,long,boolean组成
boolean | ----- | ----- | ------ |
char | 16-bit | Unicode 0 | Unicode 2^16-1 |
byte | 8-bit | -2^7(-128) | 2^7(+127) |
short | 16-bit | -2^15 | +2^15-1 |
int | 32-bit | -2^31 | +2^31-1 |
long | 64-bit | -2^63 | +2^63-1 |
float | 32-bit | IEEE754 | IEEE754 |
double | 64-bit | IEEE754 | IEEE754 |
IEEE754 不是打错了,是美国电气电子工程师协会通过的一个标准,用于计算机上表示float。 java 采用32位IEEE754 表示float,64位表示double,double之所以叫double因为他的精度是float的两倍,double 叫做双精度,double precision,float叫做单精度,single precision。double 比float更精确,也就是说double是java 目前的基本数据类型中最精确的单位。
字符串类:
常用的字符串类叫String,他不是基本数据类型,string 的优点是复制后不能随意更改,缺点也是复制后不能所以更改,所以出现了一个东西叫做Stringbuffer的类一般我们给他起名sb,stringbuffer中文翻译的意思是字符串缓冲区,意思就是1他可以变成字符串,2他可以是字符串和其他别的类型的数据中间的缓冲区。
stringbuffer是一个容器。特点是:
1 长度可以变化。
2 可以字节操作多个数据类型。
3 最终会通过toString 变成字符串。
JDK1.5之后出现了StringBuilder,StringBuilder是线程不同步的stringbuffer他们共享API,Stringbuffer在并发执行的时候不可能让别的线程的东西操作,所以stringbuffer在多线程的时候比较安全,但是在运用单线程的时候效率低下,多线程的时候stringbuffer更安全。单线程用stringbuilder更好,当然也可以在多线程的时候用stringbuilder 然后自己加锁(lock)。
基本数据类型的包装类:
数字类和char也有自己的方便转换的缓冲类,叫做基本数据类型的包装类。
除了char 的包装类是Character 以外别的都是把首字母变成大写比如byte 变成Byte ,Byte 就是byte的包装类。
包装类常用的是把基本数据类型转换成string类。比如integer 类 的34,转换成字符串就写。Integer.toString(34) 就将34装换成"34"了。
字符串转换成基本数据类型是另一个比较常用的包装类的使用方面。
int num = Integer.paeseInt("123") ;
就能将字符串“123”装换成数字int 类型的 123。
要转换成long 就写成
long l = Long.parstLong("123");
要是想把“a123”转化成数字,就给你出现numformate exception 意思就是数字类型错误。如果用等于号做大小比较
Integer m = 128;
Integer n = 128;
System.out.println(m==n);//false
System.out.println(m.equals(n));//true
Integer a = 127;
Integer b = 127;
System.out.println(a==b);//true
System.out.println(a.equals(b));//true
如果在-128 到 127 之间也就是byte 的区间范围内用等于号比较大小,就是true 如果是超出了这个范围就是false,原因是java 在byte区间内如果发现两个数值等就把引用指向同一个内存区间内,节省空间提高效率了。
集合类
集合类有点像数组的包装类,集合类可以是可变长度,和数据类型可变的数据储存容器。集合框架是集合的体系常见的集合类图有以下几种
每个不同的集合类有各自的特点对应的是不同的数据储存方法,这种方法就叫做数据结构。
Collection
collection是集合类们的父类,所以要是一个接口,接口内有增删改查等功能,也就是说他的儿子类也有同样的方法。父类的方法门:
父类有一个interator 的接口,这个接口就是提供数据集合取出和判断的抽象共性。就是取出东西的一个方法类,使用方法
for(Iterator it = 集合.iterator();it.hasNext();)
{
System.out.println(it.next());
}
首先初始化一个迭代器 然后用 集合.迭代器构造函数的方法弄出来,然后用it.hasNext()的方法判断下一个数据是否存在,在用it.next()的方法得到集合中的下一个数据。
Collection有两大子类,1List, 2 Set。
Collection 本身也有自己的方法因为是接口所以这些方法都可以应用在他的子类中
Collection 的方法摘要 | ||
---|---|---|
boolean | add(E e) 确保此 collection 包含指定的元素(可选操作)。 | |
boolean | addAll(Collection<? extendsE> c) 将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 | |
void | clear() 移除此 collection 中的所有元素(可选操作)。 | |
boolean | contains(Object o) 如果此 collection 包含指定的元素,则返回 true。 | |
boolean | containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 true。 | |
boolean | equals(Object o) 比较此 collection 与指定对象是否相等。 | |
int | hashCode() 返回此 collection 的哈希码值。 | |
boolean | isEmpty() 如果此 collection 不包含元素,则返回 true。 | |
Iterator<E> | iterator() 返回在此 collection 的元素上进行迭代的迭代器。 | |
boolean | remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 | |
boolean | removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 | |
boolean | retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 | |
int | size() 返回此 collection 中的元素数。 | |
Object[] | toArray() 返回包含此 collection 中所有元素的数组。 | |
| toArray(T[] a) 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 |
值得注意的是:
remove(Object o) --移除指定单个元素 ,如果集合而存在一个或多个(可重复元素)指定元素的则移除符合的一个元素并返回true,如果不存在返回false
removeAll(集合) --移除交集 , 移除该集合中存在的与指定集合中相同的所有元素 , 如果存在交集则移除成功返回true
retainAll(集合) --保留交集 ,移除此集合中未包含指定集合相同的元素的所有元素
List:
list 可以存储同样的元素,元素有序,该集合体系有索引,set 元素是无序的,元素不可以重复。
list特有的方法
增长:
add(index,element)
删除
remove(index)
该
set(index,element)
查
get(index);
sublist(from,to)
listIterator();
使用方法;
注意首先以下的程序很多需要挨个打印,我在这里编写一个打印方法
public static void sop(Object obj){
System.out.println(obj);
}
以后只要看见sop就是输出的意思。使用interator的时候不能再用集合本身的方法,不然会出现并发操作异常,concurrent modification exception,
ArrayList al = new ArrayList();
al.add(1);
al.add(2);
al.add(3);
al.add(4);
Iterator it = al.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(obj.equals(1)){
it.remove();
}
sop(obj);
}
sop(al);
如果把it.remove 换成了al.remove 就回发生并发操作异常。如果想要做更复杂的操作iterator 本身就不够用了,List本身的迭代器就出现了,Listiterator可以提供便利中的增删改查,把上面的程序改为以下的程序
ListIterator lit = al.listIterator()
while(lit.hasNext())
{
Object obj = lit.next();
if(obj.equals(1)){
lit.add(2);
}
sop(obj);
}
sop(al);
就能够添或者更改进去新的元素了。Listiterator 也体现了了java指针的应用比如
sop(lit.hasPrevious())
ListIterator lit = al.listIterator();
while(lit.hasNext())
{
Object obj = lit.next();
if(obj.equals(1)){
lit.add(2);
}
sop(obj);
}
sop(lit.hasNext());
sop(lit.hasPrevious());
第一个
sop(lit.hasPrevious());//输出的是flase 因为前面没有元素了
第二个
sop(lit.hasPrevious());//输出的是true 因为前面有元素了,java其实也有指针,
//通过while遍历指针已经移动到了末尾所以前边是有元素的
sop(lit.hasNext());//也是false 因为指针到了末尾了
Arraylist :
List中的方法都有
List方法摘要 | ||
---|---|---|
boolean | add(E e) 向列表的尾部添加指定的元素(可选操作)。 | |
void | add(int index,E element) 在列表的指定位置插入指定元素(可选操作)。 | |
boolean | addAll(Collection<? extendsE> c) 添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。 | |
boolean | addAll(int index,Collection<? extends E> c) 将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。 | |
void | clear() 从列表中移除所有元素(可选操作)。 | |
boolean | contains(Object o) 如果列表包含指定的元素,则返回 true。 | |
boolean | containsAll(Collection<?> c) 如果列表包含指定 collection 的所有元素,则返回 true。 | |
boolean | equals(Object o) 比较指定的对象与列表是否相等。 | |
E | get(int index) 返回列表中指定位置的元素。 | |
int | hashCode() 返回列表的哈希码值。 | |
int | indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。 | |
boolean | isEmpty() 如果列表不包含元素,则返回 true。 | |
Iterator<E> | iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器。 | |
int | lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。 | |
ListIterator<E> | listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 | |
ListIterator<E> | listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。 | |
E | remove(int index) 移除列表中指定位置的元素(可选操作)。 | |
boolean | remove(Object o) 从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。 | |
boolean | removeAll(Collection<?> c) 从列表中移除指定 collection 中包含的其所有元素(可选操作)。 | |
boolean | retainAll(Collection<?> c) 仅在列表中保留指定 collection 中所包含的元素(可选操作)。 | |
E | set(int index,E element) 用指定元素替换列表中指定位置的元素(可选操作)。 | |
int | size() 返回列表中的元素数。 | |
List<E> | subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 | |
Object[] | toArray() 返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)。 | |
| toArray(T[] a) 返回按适当顺序(从第一个元素到最后一个元素)包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 |
ArrayList 本身的方法:
boolean | add(E e) 将指定的元素添加到此列表的尾部。 | |
void | add(int index,E element) 将指定的元素插入此列表中的指定位置。 | |
boolean | addAll(Collection<? extendsE> c) 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。 | |
boolean | addAll(int index,Collection<? extends E> c) 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。 | |
void | clear() 移除此列表中的所有元素。 | |
Object | clone() 返回此 ArrayList 实例的浅表副本。 | |
boolean | contains(Object o) 如果此列表中包含指定的元素,则返回 true。 | |
void | ensureCapacity(int minCapacity) 如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 | |
E | get(int index) 返回此列表中指定位置上的元素。 | |
int | indexOf(Object o) 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。 | |
boolean | isEmpty() 如果此列表中没有元素,则返回 true | |
int | lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。 | |
E | remove(int index) 移除此列表中指定位置上的元素。 | |
boolean | remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。 | |
protected void | removeRange(int fromIndex, int toIndex) 移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 | |
E | set(int index,E element) 用指定的元素替代此列表中指定位置上的元素。 | |
int | size() 返回此列表中的元素数。 | |
Object[] | toArray() 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。 | |
| toArray(T[] a) 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 | |
void | trimToSize() 将此 ArrayList 实例的容量调整为列表的当前大小。 |
因为Arraylist 有角标,查找比较快,用角标直接就找到了。Arraylist 是线程同步的,使用时注意加锁。
add方法内的参数类型是object类,也就是说里边可以加任何数据类型的数据。
父类有一个interator 的接口,这个接口就是提供数据集合取出和判断的抽象共性。就是取出东西的一个方法类,使用方法
ArrayList al = new ArrayList();
al.add(1);
al.add(2);
for(Iterator it = al.iterator();it.hasNext();)
{
System.out.print(it.next());
}
就能打印出 12
应用1:
需求:去除ArrayList 中的重复元素
import java.util.ArrayList;
import java.util.Iterator;
//除去Arraylist 中的重复元素
public class ArrayListremoverepeat {
public static void main(String[] args) {
ArrayList ar = new ArrayList();
ar.add(1);
ar.add(1);
ar.add(2);
ar.add(2);
ar.add(3);
ar.add(3);
sop(ar);
sop(sar(ar));
}
public static ArrayList sar(ArrayList ar){
Iterator it = ar.iterator();
ArrayList ar1 = new ArrayList();
while(it.hasNext())
{
if(!ar1.contains(it.next()))
{
ar1.add(it.next());
}
}
return ar1;
}
public static void sop(Object obj)
{
System.out.print(obj);
System.out.println();
}
}
如果按上面的做结果是
[1, 1, 2, 2, 3, 3]
[1, 2, 3]
表面上看没问题但实际上有隐藏的麻烦,上边的例子中如果写
if(!ar1.contains(it.next()))
{
ar1.add(it.next());
}
当Arraylist 中储存的不是数字而是别的类的时候,会出现nosuchelementexception,所以安全起见应该改成
Object obj = it.next();
if(!ar1.contains(obj))
{
ar1.add(obj);
}
应用2:
如果arraylist中放的不是int 而是 一个叫Person 的类,类中具有名字和年龄的属性,如何去掉重复的人。
import java.util.ArrayList;
import java.util.Iterator;
//将自定义的元素存到ArrayList集合中,并且去掉重复元素
//比如:存人对象,同名同年龄,视为同一个人,为重复对象。
public class ArrayListRemoverepeatElements {
public static void main(String[] args) {
ArrayList al = new ArrayList();
<pre name="code" class="java"> al.add(new Person("ls1",30));
al.add(new Person("ls1",30));
al.add(new Person("ls2",32));
al.add(new Person("ls3",33));
al.add(new Person("ls4",35));
al = sar(al);
Iterator it = al.iterator();
while(it.hasNext())
{
Person p =(Person)it.next();
sop(p.getName()+": "+ p.getAge());
}
}
public static void sop(Object obj)
{
System.out.print(obj);
System.out.println();
}
public static ArrayList sar(ArrayList ar){
ArrayList ar1 = new ArrayList();
Iterator it = ar.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(!ar1.contains(obj))
{
ar1.add(obj);
}
}
return ar1;
}
}
class Person
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))//obj instanceof person: 在这里说,obj 是 Person吗
return false;
Person p = (Person) obj;// obj 必须转化成people 子类 不然的话obj 可不具备Person中的姓名和年龄的属性所以obj不可能调用name和age并且比较
return this.name.equals(p.name)&& this.age == p.age;
}//这个自己编写的equals方法 在运行contains 的时候被自动调用了,所以如果想比较其他类中的元素的内容可以自己编写一个有特种需求的equals方法。
}
输出结果是:
ls1: 30
ls2: 32
ls3: 33
ls4: 35
上边的例子重点是覆写了equals 方法在java调用contains 方法判断该元素是否已经在集合中存在的时候必须调用equals方法去判定,实际上除了contains中要运行equals,其他的需要定点删除或者定点更改的都需要用到equals比如remove(new Person("ls1",30))因为如果不去比较计算机怎么能知道一个叫ls1 的30岁的Person是不是在Arraylist 中。只有在知道了之后才能准确的删除那个地址中关于这个人的信息。
Linkedlist
链表就是前一个和后一个相互知道对面的空间里的元素是什么,特点是增删很快,让前后记住了新的目标就OK了,但是查找就很慢了。Linkedlist 特有的方法:
addFirst();总是把元素查到链表的头部,后插的在链表的头里。addlast()和addfirst()一样就是倒过来
removeFirst();取出第一个,并且得到第一个,之后链表以前的第一个就没了, 第二个晋升为第一个,removelast也是同样的道理。
获取元素,但是元素被删除,如果集合中没有元素,就回出现nosuchelementexception。
在JDK1.6之后出现了
offerfirst(), 添加元素
peekfirst (),获取元素,但是不删除元素,如果集合中无元素,返回null
pollfirst(),获取并且添加元素,如果集合为空,返货null
应用1:
需求:如果想设计一个堆栈形式的先进后出的的数据结构
提示:利用addfirst 和 removefirst 方法或者利用offerfirst 和pollfirst 方法。
import java.util.LinkedList;
public class LinkedListline {
public static void main(String[] args) {
DuiLie dl = new DuiLie();
dl.myAdd(1);
dl.myAdd(2);
dl.myAdd(3);
dl.myAdd(4);
while(!dl.isNull())
{
sop(dl.myGet());
}
}
public static void sop(Object obj)
{
System.out.print(obj);
}
}
class DuiLie
{
private LinkedList link;
DuiLie()
{
link = new LinkedList();
}
public void myAdd(Object obj){
link.addFirst(obj);
}
public Object myGet(){
return link.removeLast();
}
public boolean isNull()
{
return link.isEmpty();
}
}
增删频繁查询不多用Linkedlist,增删少查询多用Arraylist,如果发现实在不知道选什么了,根据毕向东老师的总结,还是选Arraylist。
Vector:底层是数组数据结构,功能和Arraylist 一样,Vector比较出现的早,Arraylist 是子类,vector 是线程同步的。Arraylist 的默认长度是10,过了10 每一次添加都初始化一个新的数组,每一次添加都增加50个percentage 的长度。vector 的初始长度也是10,出现了超出就增加100 个 percentage的延长。