java-基础-基本数据类型

时间:2022-01-07 15:52:39

引用原文:

http://www.cnblogs.com/zhenjing/archive/2013/04/25/java_Container.html

//http://blog.csdn.net/mad1989/article/details/26389541

java-基础-基本数据类型

线性表,链表,哈希表是常用的数据结构

Collection
List
│├LinkedList
│├ArrayList
│└Vector
│└Stack
Set
Map

├Hashtable
├HashMap
└WeakHashMap

Collection接口

   Collection是最基本的集合接口,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
   如何遍历Collection中的每一个元素:
    Iterator it = collection.iterator(); // 获得一个迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一个元素
    }

List接口

  List是有序的Collection,List允许有相同的元素。
   除具有iterator()方法外,有listIterator()方法,返回一个 ListIterator接口多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。
  实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

LinkedList类

   允许null元素。提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
  注意没有同步方法。多个线程必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
  List list = Collections.synchronizedList(new LinkedList(...));

ArrayList类

  ArrayList实现了可变大小的数组。ArrayList没有同步。
    每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并 没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。

Vector类

   Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例 如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该 异常。

Stack 类

   Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。

Set接口

  Set是一种不包含重复的元素的Collection
  请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

Map接口

   请注意,Map没有继承Collection接口,Map提供key到value的映射。

Hashtable类

  Hashtable继承Map接口,实现一个key-value映射的哈希表。
  添加数据使用put(key, value),取出数据使用get(key),时间开销为常数。
Hashtable 通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。
使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是”one”,”two”,”three”:
    Hashtable numbers = new Hashtable();
    numbers.put(“one”, new Integer(1));
    numbers.put(“two”, new Integer(2));
    numbers.put(“three”, new Integer(3));
  要取出一个数,比如2,用相应的key:
    Integer n = (Integer)numbers.get(“two”);
    System.out.println(“two = ” + n);
   由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方 法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相 同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如 果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希 表的操作。
  避免相同的对象有不同的hashCode:要同时复写equals方法和hashCode方法
  Hashtable是同步的。

HashMap类

   HashMap和Hashtable类似,HashMap是非同步的,并且允许null,即null value和null key

WeakHashMap类

  WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。

总结
  如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
  如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
  要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
  尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。


Map简单应用

public static void main(String[] args){
//Map<String,String> pets=new HashMap<String, String>();
Map<String,String> pets=new TreeMap<String, String>();
pets.put("1","张三");
pets.put("2","李四");
pets.put("3","王五");
if (pets.containsKey("1")){
System.out.println("已存在键1");
}
if (pets.containsValue("张三")){
System.out.println("已存在值张三");
}
Set<String> sets=pets.keySet();
Set<Map.Entry<String , String>> entrySet= pets.entrySet();
Collection<String> values= pets.values();
for (String value:values){
System.out.println(value+";");
}
for (String key:sets){
System.out.print(key+";");
}
for (Map.Entry entry:entrySet){
System.out.println("键:"+entry.getKey());
System.out.println("值:"+entry.getValue());
}
}

String、StringBuffer、StringBuilder区别

String类是不可变类,任何对String的改变都 会引发新的String对象的生成

StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象。StringBufferd支持并发操作,线性安全的,适合多线程中使用

StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。

基本应用示例

package com.scalalearn.java.main.JavaContainer;

/**
* Created by hjw on 17/5/19.
*/
import java.lang.String;
import java.util.*;

//http://www.cnblogs.com/zhenjing/archive/2013/04/25/java_Container.html
//http://blog.csdn.net/mad1989/article/details/26389541
public class ContainerLearn {

public static void main(String[] args) throws Exception {

System.out.println("\n============StringBuffer====StringBuilder============");
{
//StringBuffer常用方法(StringBuffer和StringBuilder在使用上几乎一样)
//------初始化-----
StringBuilder s = new StringBuilder();
//分配了长度512字节的字符缓冲区。
StringBuilder sb1 = new StringBuilder(512);
//创建带有内容的StringBuilder对象,在字符缓冲区中存放字符串“how are you?”
StringBuilder sb2 = new StringBuilder("how are you?");


//-------append方法
//该方法的作用是追加内容到当前StringBuilder对象的末尾,类似于字符串的连接,调用该方法以后,StringBuilder对象的内容也发生改 变,例如:
StringBuilder sb3 = new StringBuilder("abc");
//则对象sb3的值将变成”abcappend”
sb3.append("append");
//装成最后所用的字符串
sb3.toString();

// ------deleteCharAt方法
//该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuilder sb = new StringBuilder("KMing");
sb. deleteCharAt(1);
//该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变 为”King”。
System.out.println(sb);


//-------delete方法:
//public StringBuffer delete(int start,int end)
//该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuilder sb4 = new StringBuilder("TestString");
//该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
System.out.println(sb4.delete (1,4));


// ----insert方法
//public StringBuffer insert(int offset, boolean b),
// 该方法的作用是在StringBuilder对象中插入内容,然后形成新的字符串。例如:
StringBuilder sb5 = new StringBuilder("TestString");
// 该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
System.out.println(sb5.insert(4,false));


//---reverse方法

//该方法的作用是将StringBuilder对象中的内容反转,然后形成新的字符串。例如:
StringBuilder sb6 = new StringBuilder("abc");
//经过反转以后,对象sb中的内容将变为”cba”。
System.out.println(sb6.reverse());;


//-----setCharAt方法
//该方法的作用是修改对象中索引值为index位置的字符为新的字符ch,返回值为void。例如:
StringBuilder sb7 = new StringBuilder("abc");
//则对象sb的值将变成”aDc”。
sb7.setCharAt(1,'D');
System.out.println(sb7);


// -----trimToSize方法
// public void trimToSize()
// 该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费,和String的trim()是一样的作用
// sb.capacity方法
// 该方法的作用是获取字符串的容量。
StringBuilder sb8 = new StringBuilder(8);
sb8.append("abc");
System.out.println("sb8.capacity:" + sb8.capacity() + "\tsb8.length:" + sb8.length());
//sb8.capacity:8 sb8.length:3
sb8.trimToSize();
System.out.println("sb8.capacity:" + sb8.length());
//sb8.capacity:3


// -----setlength方法
// 该方法的作用是设置字符串缓冲区大小。
// sb.ensureCapacity(32); //预先设置sb的容量为32,该方法的作用是重新设置字符串容量的大小。
StringBuilder sb9=new StringBuilder("abcd");
// 如果用小于当前字符串长度的值调用setlength()方法,则新长度后面的字符将丢失。
sb9.setLength(3);
System.out.println(sb9);
//abc

// ----getChars方法
// 该方法的作用是将字符串的子字符串复制给数组。
// getChars(int start,int end,char chars[],int charStart);
StringBuffer sb10 = new StringBuffer("I love You");
int begin = 0;
int end = 5;
// //注意ch字符数组的长度一定要大于等于begin到end之间字符的长度
// //小于的话会报ArrayIndexOutOfBoundsException
// //如果大于的话,大于的字符会以空格补齐
char[] ch = new char[end-begin];
sb10.getChars(begin, end, ch, 0);
System.out.println(ch);
//I lov
}


// Interfaces:
// Interface Iterator: hasNext(), next(), remove() ---- 所有容器通用的遍历方式。
// Interface Collection:add(E e),remove(Object o), clear(), isEmpty(), size(), iterator(), toArray() ---- 所有单值容器(map除外)的公共接口。
// Interface Map: put(K key, V value), get(Object key), remove(Object key), clear(),isEmpty(),size(), keySet(), entrySet(), values() ---- 所有K-V容器的公共接口,常见class: HashMap, Hashtable, IdentityHashMap, LinkedHashMap, ConcurrentHashMap
// Interface Map.Entry: getKey(), getValue(), setValue(V value) ---- 用于遍历Map容器。

// ============Arrays============
{
System.out.println("\n============Arrays============");
String[] array = new String[] { "a", "b", "c" };
//-----转List
List list = Arrays.asList(array);

//List.size
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + ";");
}

//foreach
System.out.println();
for (Object val : array) {
System.out.print( val + ";");
}
}


// ============ArrayList============
{
System.out.println("============ArrayList============");
ArrayList arraylist = new ArrayList();

/*
add()直接添加到最后
add(index,value)在index位置添加元素,该位置及之后的原值依次后移,当index>目前的length抛出异常IndexOutOfBoundsException
set(index,value)更改index位置处的元素
*/
arraylist.add(0, "end");//指定索引加入值

for (int i = 0; i < 2; i++) {
arraylist.add(i, String.valueOf(i));
}
System.out.println(arraylist);
//[0, 1, end]

System.out.println("ArrayList's lastIndexOf(\"end\") is " + arraylist.lastIndexOf("end"));
System.out.println("ArrayList's lastIndexOf(\"0\") is " + arraylist.lastIndexOf("0"));
System.out.println("ArrayList's lastIndexOf(\"1\") is " + arraylist.lastIndexOf("1"));
System.out.println();
// ArrayList's lastIndexOf("end") is 2
// ArrayList's lastIndexOf("0") is 0
// ArrayList's lastIndexOf("1") is 1

arraylist.add("2");
System.out.println(arraylist);
// [0, 1, end, 2]
System.out.println("ArrayList's lastIndexOf(\"2\") is " + arraylist.lastIndexOf("2"));
// ArrayList's lastIndexOf("2") is 3
// arraylist.add(5,"3");
// java.lang.IndexOutOfBoundsException: Index: 5, Size: 4
arraylist.add(3,"3");
// [0, 1, end, 3, 2]
System.out.println(arraylist);
arraylist.set(3,"4");
System.out.println(arraylist);
// [0, 1, end, 4, 2]

System.out.print("ArrayList遍历1:");
for (Object val : arraylist) {
System.out.print( val + ";");
}
System.out.println();
System.out.print("ArrayList遍历2:");
for (int i = 0; i < arraylist.size(); i++) {
System.out.print(arraylist.get(i) + ";");
}
}
// ============Vector============
{
System.out.println("\n============Vector============");
Vector vector = new Vector();
vector.add(0, "b");
vector.add("a");
vector.addElement("d");
vector.add("c");
System.out.println(vector);

vector.set(2, "h");//替换掉指定索引的元素
System.out.println(vector);

Object[] str = vector.toArray();
for (int i = 0; i < str.length; i++) {
System.out.print(str[i] + ";");
}
vector.setSize(2);//重新设置大小为2
System.out.println(" " + vector);
}

// ============LinkedList============
{
System.out.println("\n============LinkedList============");
LinkedList linkedlist = new LinkedList();//*使用是它的特色
linkedlist.add("a");
linkedlist.add(1, "c");
linkedlist.addLast("b");
linkedlist.addFirst("d");
System.out.println(" LinkedList:");
System.out.println(linkedlist);
// linkedlist.clear();//该方法清空容器
// linkedlist.remove(0);//删除索引为0的元素
// linkedlist.remove("d");//删除值为d的元素
// linkedlist.removeFirst();//删除第一个元素
// linkedlist.removeLast();//删除最后一个元素
for (int i = 0; i < linkedlist.size(); i++) {
System.out.print(linkedlist.get(i) + ";");
}
System.out.println("\n");
}

// ============Stack============
{
System.out.println("\n============Stack============");
Stack stack = new Stack();//堆栈
stack.add("b");
stack.add(0, "c");
stack.push("d");
stack.add("e");
stack.push("a");
System.out.println(stack);
//[c, b, d, e, a]
System.out.println("peek:" + stack.peek());
//peek:a

System.out.print("遍历(是从底开始的):");
Enumeration enumeration = stack.elements();
while (enumeration.hasMoreElements()) {
System.out.print(enumeration.nextElement() + ";");
}
//遍历(是从底开始的):c;b;d;e;a;

// 后进先出
System.out.println("\npop:" + stack.pop());
//pop:a

//是否包含该元素
System.out.println(stack.contains("d") + ";" + stack.contains("a"));

//检索是从栈顶开始(栈顶index=0)
System.out.println(stack.search("c"));
System.out.println("\n");
}



// ============Collections============
{
System.out.println("\n============Collections============");
String[] array = new String[] { "a", "b", "c" };
List list = Arrays.asList(array);

//Collections.fill
Collections.fill(list, "Fill");//用Fill填充全部元素
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + ";");
}

//Collections.copy
array = new String[] { "1", "2", "3" };
List list2 = Arrays.asList(array);
Collections.copy(list, list2);//拷贝list2的数据进list
System.out.println(" " + list);

//Collections.swap
Collections.swap(list, 2, 1);//调换索引为1和2的元素的位置
System.out.println(list);
//============Collections============
//Fill;Fill;Fill; [1, 2, 3]
//[1, 3, 2]
}


// ============HashMap=====LinkedHashMap====TreeMap===
{
System.out.println("\n============HashMap============");
HashMap hashmap = new HashMap();//一个速度最快的容器
hashmap.put("0", "c");
hashmap.put("1", "a");
System.out.println(hashmap);//该容器有其内部的排序方式


System.out.println(hashmap.containsKey("1"));//是否包含这个键
System.out.println(hashmap.containsValue("c"));//是否包含值

Set set = hashmap.keySet();//获取全部键
System.out.println("\nHashMap: K-V");
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object key = iterator.next();
System.out.print(key+":"+hashmap.get(key) + ";");
}

System.out.println("\nHashMap(Entry): K-V");
Set<Map.Entry> kvSet = hashmap.entrySet();
Iterator<Map.Entry> it = kvSet.iterator();
while (it.hasNext()){
Map.Entry entry = it.next();
System.out.print( entry.getKey()+":" + entry.getValue() +";");
}
System.out.println();

for (Map.Entry entry:(Set<Map.Entry>)hashmap.entrySet()){
System.out.print("键:"+entry.getKey());
System.out.print("-值:"+entry.getValue() + " ;");
}
System.out.println("\n");
}

// ============HashSet====LinkedHashSet=====TreeSet===
{
System.out.println("\n============HashSet============");
HashSet hashset = new HashSet();//一个绝对不能重复的类型
hashset.add("c");
hashset.add("b");
hashset.add("a");
hashset.add("a");
hashset.add("b");
System.out.println(hashset);

Iterator iterator = hashset.iterator();//取出元素
while (iterator.hasNext()) {
System.out.print(iterator.next() + ";");
}
System.out.println("\n");
}


// Hashtable
{
System.out.println("\n============Hashtable============");
Hashtable hashtable = new Hashtable();//线程同步的
hashtable.put("0", "c");
hashtable.put("1", "a");
hashtable.put("3", "c");
hashtable.put("2", "b");
Enumeration enumeration = hashtable.elements();//获取元素,Enumeration已经不是主流,Iterator是它的下一代替代品
while (enumeration.hasMoreElements()) {
System.out.print(enumeration.nextElement() + ";");
}
System.out.println("\n");
}
}
}