那么我将按照以下顺序进行讲解,感觉难度也是逐步提升
下面开始我的表演
ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问
其实吧,个人理解他就是个数组,只不过封装了,有各种操作。
ArrayList a = new ArrayList();
ArrayList b = new ArrayList();
这里的Integer可以换成任何其他类。
第一种定义可以不指明ArrayList的类型,那么插入的数据可以是任意类型;
第二种明确了类型,只能插入相应类型的数据。
1. add( Object obj ); 加入元素到尾部
a.add(2);
a.add( new person("小明",1) );
b.add(4);
b.add(5);
因为之前的a我们没指名类型,所以我们可以add任意类型的东西进去,b就只能add Integer类型的。
这个绝逼是最常用的,相当于C++里面的push_back();
至于他的返回值,是boolean,也就是C++的bool,表示是否add成功,但是返回值我们一般不用
然后add还可以指定位置
add( int index,Object obj);
b.add(1, 222); //在1位置处插入222,后面的元素index加1(如果有的话)
这个带插入位置的add就相当于C++的insert,在某个位置插入一个元素,使后面的元素后移。
但是个人建议不要用这个,这个插入效率比较低。
2.get( int index ); 得到指定位置的元素
int t = (Integer)a.get(0); //下标是从0开始的
person p = (person)a.get(1);
int t2 = b.get(0);
int t3 = b.get(1);
这里我们注意到a的get都要强制转换,而b不需要,因为a在定义时候就没有明确,所以这是必然的。
3.remove( int index ) 删除指定位置的元素,后面元素向前挪
a.remove(0);
它的返回值也是boolean,表示是否删除成功。
同样,因为是数组实现,所以删除效率就很低。
4.int size(); 得到ArrayList的大小
int t = b.size();
常用而又简单
5.sort( Comparator c ); 进行排序,还需要定义比较器,个人觉得比较麻烦
b.sort( new mycomparator() );
//定义 mycomparator
class mycomparator implements Comparator
{
public int compare(Integer o1, Integer o2)
{
if( o1 > o2 )
return 1;
return -1;
}
}
如果觉得不太理解可以去查查Java排序的相关知识
6.void clear(); 清空
a.clear();
就和C++的clear一样
下面是ArrayList用法小汇总,大家可以举一反三
import java.util.*;
public class Main
{
public static void main( String args[] )
{
ArrayList a = new ArrayList(); //定义ArrayList 不明确类型
a.add(1);
a.add( new Person("小明",12) );
a.add(0, 123); //在0位置处插入123
int t = (int)a.get(0); //不加强制转化 会报错
System.out.println(t); //输出t 结果是123
a.remove(0); //删除位置0处的元素,后面的向前面移动
for( int i = 0 ; i < a.size() ; i++ ) //遍历ArrayList
System.out.println( a.get(i) );
a.clear(); //清空
if( a.isEmpty() ) //调用 isEmpty方法
System.out.println("ArrayList已经空了");
}
}
class Person
{
String name;
int age;
Person( String name,int age )
{
this.name = name;
this.age = age;
}
public String toString()
{
return "name "+name+"\n"+"age "+age;
}
}
其实Vector和ArrayList简直是一模一样,至少操作是这样
如果想了解它们的区别,可以参考
https://www.cnblogs.com/zhangzongle/p/5432212.html
LinkedList的基本用法其实和ArrayList差不多,但是它的储存方式和之前的不一样,所以还是有一丢丢不同。
总的来说,LinkedList 增加和删除效率要比ArrayList要高。 毕竟是链表,改一下指针就行了
但是访问的效率并不高。
LinkedList l = new LinkedList();
LinkedList ll = new LinkedList();
add( Object obj)、remove(int index)、size()、isEmpty()、sort()、clear()这些都和之前的一样,我就不讲啦
不同的有:
void addFirst( Object obj ); //队首插入
void addLast( Object obj ); //队尾插入,和add( Object obj )效果一样
l.addFirst(1);
l.addLast(2);
同样remove也有两种
Object removeFirst( );
Object removeLast( );
当然,返回值可以要,也可以不要
l.removeFirst();
l.removeLast();
int t = (int)l.removeLast();
int t2 = (int)l.removeFirst();
下面是LinkedList的用法小汇总
import java.lang.reflect.Array;
import java.math.*;
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Person p1 = new Person("小明",12);
Person p2 = new Person("小红",16);
Person p3 = new Person("小哥哥",13);
LinkedList ll = new LinkedList(); //定义一个LinkedList
ll.add(p1);
ll.add(p2);
ll.add(p3);
ll.sort( new mycomparator() ); //进行排序
ll.addFirst( new Person("大哥",22) );
for( int i = 0 ; i < ll.size() ; i++ )
System.out.println( ll.get(i) );
ll.removeFirst();
ll.removeLast();
Person temp = ll.removeFirst(); //删除第一个
ll.removeFirst();
if( ll.isEmpty() ) //调用isEmpty方法
System.out.println("LinkedList空了");
else
{
Person tt = ll.get(0); //get函数
ll.removeFirst();
}
ll.clear(); //清空
}
}
class Person
{
String name;
int age;
public Person( String name,int age )
{
this.name = name;
this.age = age;
}
public String toString()
{
return "name "+name+"\n"+"age "+age;
}
}
class mycomparator implements Comparator
{
public int compare(Person a, Person b ) //年龄从大到小排序
{
if( a.age < b.age )
return 1;
return -1;
}
}
Stack意思是栈,具有先进后出的特点
与C++不同的是,Java的Stack遍历方式可以多样,因为Stack可以取到任意位置的值,而C++只能中规中矩的遍历。
可见Java的操作比C++更多
Stack s = new Stack();
Stack ss = new Stack();
push( Object obj ); 插入元素到栈顶
add( Object obj ); 插入元素到尾部 效果和push一样
Stack s = new Stack();
s.push(1);
s.add(2);
boolean empty(); 判断队列是否为空
Object peek(); 取栈顶元素
Object pop(); 删除栈顶元素,返回的是删除的元素
int size(); 返回栈的大小
结合以上几个方法,我们可以写出Stack的两种遍历方法
System.out.println("遍历");
for( int i = s.size()-1 ; i >= 0 ; i-- ) //从后往前遍历
System.out.println(s.get(i) );
System.out.println("遍历");
while( s.empty() == false )
{
int t = s.peek();
s.pop();
System.out.println(t);
}
void sort(); 之前已经讲过啦,参加ArrayList的sort
void clear(); 清空
下面是Stack用法小汇总
public class Main
{
public static void main(String[] args)
{
Stack s = new Stack();
s.push(1);
s.add(2); //add和push效果一样
s.push(3);
System.out.println( "位置为 1的地方是 "+ s.elementAt(1) ); //调用elementAt方法
System.out.println("从前向后遍历");
for( Integer i:s ) //从前向后遍历 用到了foreach循环
System.out.println(i);
System.out.println("从后向前遍历");
for( int i = s.size()-1 ; i >= 0 ; i-- ) //从后往前遍历
System.out.println(s.get(i) );
System.out.println("类似C++Stack的遍历");
while( s.empty() == false )
{
int t = s.peek();
s.pop();
System.out.println(t);
}
s.clear(); //清空栈
}
}
Queue就是队列,具有先进先出的特点
在Java中,没有Queue这个类,而是用到了LinkedList,所以我们定义的时候有点特殊
Queue q = new LinkedList();
Queue qq = new LinkedList();
boolean add( Object obj ); 向队列中插入一个元素
boolean offer( Object obj ); 向队列中插入一个元素
可以看出两个方法的功能一样,但是推荐使用第二个,在网上看的说add操作失败时会抛出异常,有点不是很明白
如果有问题的可以自己去百度一下吧
Object peek(); 返回队首元素
Object poll(); 删除并返回队首元素
当然因为是LinkedList实现的,所以LinkedList有的操作它都有,那么我就偷一下懒,不写啦
下面是Queue用法小汇总
public class Main
{
public static void main(String[] args)
{
Queue q = new LinkedList(); //定义一个Sting类的Queue
q.add("1"); //向队首加入元素
q.offer("1"); //功能与上一个一样,但是推荐使用第二个
q.offer("2");
q.offer("3");
q.poll(); //删除队首元素
String t = q.peek(); //取队首元素
System.out.println("foreach 遍历队列");
for( String s:q )
System.out.println(s);
System.out.println("类似C++的队列遍历");
while( q.isEmpty() == false )
{
String s = q.peek();
q.poll();
System.out.println(s);
}
q.clear();
}
}
Set表示集合,不能允许元素重复
Set又包括HashSet和TreeSet,第一个不自动排序,第二个自动排序
C++中STL有MultiSet(允许元素重复),而Java中自带的没有,似乎要自己去下载。
另外,Set是一个借口,不能实例化一个Set对象
Set继承Collection借口,所以有Collection的常见操作
Set s1 = new HashSet();
Set s2 = new TreeSet();
//或者
HashSet s3 = new HashSet();
TreeSet s4 = new TreeSet();
这里我偷一下懒,直接放张图片,嘻嘻
下面是Set用法小汇总
public class Main
{
public static void main(String[] args)
{
Set s1 = new HashSet();
Set s2 = new TreeSet();
s1.add("ABC");
s1.add("ABC");
s1.add("AAA");
s2.add("AB");
s2.add("BB");
s2.add("CC");
System.out.println("遍历HashSet");
Iterator it = s1.iterator();
while( it.hasNext() )
{
String t = it.next();
System.out.println(t);
}
s1.remove("ABC"); //删除ABC
if( s1.contains("ABC") ) //调用contains方法,判断Set是否包含某个元素
System.out.println("ABC 还在");
if( s1.isEmpty() ) //使用 isEmpty方法
System.out.println("s1空了");
System.out.println("遍历TreeSet");
Iterator it2 = s2.iterator(); //TreeSet结果会自动排序
while( it2.hasNext() )
{
String t = it2.next();
System.out.println(t);
}
s1.clear(); //清空
s2.clear();
}
}
个人感觉Map是常用的数据结构里面最难的。
首先我们要知道map储存数据的方式,map储存数据的形式是一个key和一个value对应,即Map
Map m = new HashMap(); //String 到 int的映射
put( Object Key,Object Value ); 插入一组值
remove( Object Key ); 删除键值为Key的那一组
get( Object Key ); 得到键值为Key的那一组的Value
entrySet(); 得到Pair集合(个人是这样理解的,pair就是一组)
keySet(); 得到Key集合
values(); 得到values集合
要想搞清楚Map,就要先搞清楚Key,Value和Entry的区别,
例如 Map
中,String就是Key,Integer就是Value,而
所有组Entry构成了EntrySet
所有Key构成KeySet,同样所有Value构成ValueSet
下面是Map用法小汇总:
主要理解遍历啊
public class Main
{
public static void main(String[] args)
{
Map m = new HashMap(); //String 到 int的映射
m.put("小明", 12);
m.put("小红", 11); //向Map中插入一组值
m.put("小呆", 20);
m.remove("小呆"); //删除Key为小呆的一组值
Integer t = m.get("小明"); //得到key为小明所在的值
System.out.println(t); //得到结果为12
//下面是Map的4种遍历方法
System.out.println("Map遍历方法1:KeySet遍历"); //通过Key找Value,可想效率不是很高
for( String key: m.keySet() )
System.out.println(" Key:"+key+" "+"value:"+m.get(key) );
System.out.println("Map遍历方法2:ValueSet遍历"); //只遍历Map的value,不能遍历Key,所以有缺陷,但是比较快
for( Integer i:m.values() )
System.out.println("value "+i);
System.out.println("Map遍历方法3: EntrySet遍历"); //遍历Map的每一组,推荐使用这种方法
for( Map.Entry entry : m.entrySet() )
System.out.println(" Key "+entry.getKey()+ " "+"value: "+entry.getValue() );
System.out.println("Map遍历方法4: EntrySet+Iterator遍历"); //比较复杂
Iterator< Map.Entry > it = m.entrySet().iterator();
while( it.hasNext() )
{
Map.Entry entry = it.next();
System.out.println(" Key "+entry.getKey()+ " "+"value: "+entry.getValue() );//这一步和上一种遍历一样
}
}
}
另外Map还有一个HashTable,但是两者的差别是非常小的,而且HashTable已经快被淘汰
感兴趣的可以参考下面链接
http://www.importnew.com/24822.html
虽然我将的顺序是这样,但是分类的顺序却有些不一样
List接口是被四个类实现了
分别是ArrayList、LinkedList、Vector、Stack
Map接口是两个
HashMap、HashTable
Set接口是两个
HashSet、TreeSet
Queue接口是一个
所以我想说的是,编程时应该养成使用接口定义的好习惯,
即如果定义ArrayList ,用 List a = new ArrayList(); 而不是 ArrayList a = new ArrayList();
如果定义LinkedList ,用 List ll = new LinkedList(); 而不是 LinkedList ll = new LinkedList();
至于为什么,
一句话,更灵活一些。
----------------------------------------------------------------------------------------------------------------------------------------------------
以上就是Java的常用数据结构啊,楼主知识短浅,还望多多指正。
第一次编辑,以后还会再回来看的。
---------------------2018/11/1