6.3 String类和StringBuffer类 - 6.6 hashtable与properties类

文章介绍了Java中String和StringBuffer类的区别和使用,强调String对象不可变而StringBuffer可变的特点。还讨论了如何使用equalsIgnoreCase方法进行不区分大小写的字符串比较。此外,文章提到了Vector类和Enumeration接口作为动态数据结构,以及后来的Collection和Iterator接口的引入。最后,文章涉及了Hashtable和Properties类在数据检索和配置文件读取中的应用。
摘要由CSDN通过智能技术生成

 Java定义了String和StringBuffer 两个类来封装对字符串的各种操作。它们都被放到了javalang 包中不需要用importjavalang 这个语句导入该包就可以直接使用它们。

String 类用于比较两个字符串、查找和抽取串中的字符或子串、字符串与其他类型之间的相互转换等。String 类对象的内容一旦被初始化就不能再改变。

StringBuffer 类用于内容可以改变的字符串,可以将其他各种类型的数据增加、插入到字符串中,也可以翻转字符串中原来的内容。一旦通过 StringBuffer 生成了最终想要的字符串,就应该使用 StringBuffer.toString 方法将其转换成 String 类,随后,就可以使用 String类的各种方法操纵这个字符串了
Java 为宁符串提供了特别的连接操作符(+),可以把其他各种类型的数据转换成字符串,并前后连接成新的字符串。连接操作符(+)的功能是通过StringBuffer 类和它的append方法实现的。

 

public class ReadLine{
	public static void main(String [] args){
		byte buf[] = new byte[1024];
		String strInfo = null;
		int pos = 0;
		int ch = 0;
		System.out.println("please enter info, input bye for exit");
		while(true){
			try{
				ch = System.in.read();
			}catch(Exception e){
				System.out.println(e.getMessage());
			}switch(ch){
				case '\r':
				break;
				case '\n':
				strInfo = new String(buf,0,pos);
				if(strInfo.equals("byte"))
					return;
				else
					System.out.println(strInfo);
					pos = 0;
					break;
				default:
					buf[pos++] = (byte)ch;
			}
		}
	}
}

 equalsIgnoreCase(String anotherString)是在比较两个字符串时忽略大小写,这在实际应用中用的非常多,比如我们上面输入和打印字符的例子,只能是输入小写的“bye”才能结束,其实还可以把它做的更友好一些,如输入“BYE”和“Bve”等都能正确退出。这时只需把程序中的if(strInfo.equals(“bye”)改为f(strInfo.equalsIgnoreCase(“bye”))就行了

还有这样一种情况:我们在编写的程序中有一个用户登录界面,需要将用户的姓名与数据库里面的姓名进行比较,这时如果我们用以前的 equals 方式来比较,就可能出错,比如程序可能认为 Tom和 tom 不是一个人,这样的程序就太不友好了。要想让程序友好一些不出这样的错误,就要用方法equalsIgnoreCase 来做姓名这个字段的验证。

indexOf(int ch)方法是用来返回一个字符在该字符串中的首次出现的位置,如果没有这个字符则返回“-1”。它的另一种形式indexOf(int chint fromIndex)返回的是从fromIndex指定的数值开始,ch 字符首次出现的位置。该方法可以应用于文件和数据库内容的查找等功能

subString(intbeginIndex)方法返回的是在一个字符串中从beginIndex指定的数值到末尾的一个字符串,如果 beginndex 指定的数值超过了当前字符串的长度,则返回一个空字符它返回的是当前字串。这个方法也有另外一种形式substring(int beginIndex,int endIndex),'符串中从 beginIndex开始到endIndex-1结束的一个字符串

关于这两个类的其他方法,读者要自己查阅JDK 文档资料了。看完文档中所有 String类的方法后,你也许会问:“String 类中的 replace 和 toUpperCase 方法不都能改变字符串的内容吗?这与你先讲的String 类对象的内容一旦被初始化就不能再改变’不是自相矛盾吗?”,请你再仔细看一下这两个函数的帮助,他们的返回类型都是 String 类,即生成一个新的字符串,而不是改变原来的字符串内容。

Java 对数据既提供基本数据的简单类型,也提供了相应的包装类(也有的书中叫包裹类)。使用基本简单数据类型,可以改善系统的性能,也能够满足大多数应用需求。但基本简单类型不具有对象的特性,不能满足某些特殊的需求。从JDK 中,我们知道,Java 中的很多类的很多方法的参数类型都是 Obiect,即这些方法接收的参数都是对象,同时,我们又需要用这些方法来处理基本数据类型的数据,这时就要用到包装类。比如,用Integer类来包装整数。关于这种应用,我们在后面讲解 Vector 类的例子程序中就要碰到。另外,包装类对象在进行基本数据类型的类型转换时也特别有用,如整数与字符串的转换。下面的程序用于在屏幕上打印出一个星号 (*组成的矩形,矩形的宽度和高度通过运行时为程序传递的参数指定。

public class TestInteger {
    public static void main(String[] args) {
        int w = Integer.parseInt(args[0]);
        int h = new Integer(args[1]).intValue();
        //int h = Integer.valueOf(args[1]).intValue();
        for (int i = 0; i < h; i++) {
            StringBuffer sb = new StringBuffer();
            for (int j = 0; j < w; j++) {
                sb.append('*');
            }
            System.out.println(sb.toString());
        }
    }
}

1.Vector 类与 Enumeration 接口

Vector类是Java语言提供的一种高级数据结构,可用于保存一系列对象,Java 不支持动态数组,Vector 类提供了一种与“动态数组”相近的功能。如果我们不能预先确定要保存的对象的数日,或是需要方便获得某个对象的存放位置时,Vector 类都是一种不错的选择

import java.util.*;


public class TestVector {
    public static void main(String[] args) {
        int b = 0;
        Vector v = new Vector();
        System.out.println("Please Enter Number");
        while (true){
            try {
                b=System.in.read();
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
            if (b=='\r'||b=='\n')
                break;
            else {
                int num=b-'0';
                v.addElement(new Integer(num));
            }
        }
        int sum=0;
        Enumeration e = v.elements();
        while (e.hasMoreElements()){
            Integer intObj = (Integer) e.nextElement();
            sum +=intObj.intValue();
        }
        System.out.println(sum);
    }
}

        Enumeration是一个接口类,它提供了一种访问各种数据结构(Vector类只是众多数据结构中的一种)中的所有数据的抽象机制,就是我们要访问各种数据结构对象中的所有元素时,都可以使用同样的方式,调用同样的方法。有了这样的数据结构接口,就很容易学通百,以不变应万变了。
2.Collection 接口与 Iterator 接口
Java 2平台发布后,Java 设计者又推出了一套综合的数据结构,这些数据结构类的基本接口是 Collection,它的使用非常类似上面讲过的 Vector类,只是方法的名称不同。我们要取出保存在实现了 Collection 接口对象中的所有对象,我们也必须通过 Collectioniterator方法返回一个Iterator 接口对象,Iterator 接口的功能与使用同Enumeration 接口非常相似。Java 2平台的数据结构类设计人员本可以扩展 Enumeration 接口,而不用创建Iterator这个新接口。但他们不喜欢 Enumeration 接口方法长的名字,因而创建了 Iterator这个新接口并缩短了方法名长度。
按照Java的语法,不能直接用 Collection 接口类创建对象,而必须用实现了 Collection接口的类来创建对象,ArrayList 类就是一个实现了 Collection 接口的类,我们将上面使用Vector 和Enumeration 的例子改为用ArrayList 和Iterator 编写,读者就应该基本明白了这些类之间的关系和用法

import java.util.*;

public class TEstCollection {
    public static void main(String[] args) {
        int b =0;
        ArrayList al = new ArrayList();
        System.out.println("Please Enter Number:");
        while (true){
            try {
                b=System.in.read();
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
            if (b=='\r'|b=='\n')
                break;
            else {
                int num=b-'0';
                al.add(new Integer(num));
            }
        }
        int sum=0;
        Iterator itr = al.iterator();
        while (itr.hasNext()){
            Integer intObj = (Integer) itr.next();
            sum+=intObj.intValue();
        }
        System.out.println(sum

        );
    }
}

ArrayList 类中的所有方法是非同步的,所以在没有多线程安全问题时,最好用ArrayList,程序的效率会高些。在有线程安全问题,且我们的程序又没有自己处理(自己处理是指对调用ArrayList 的代码或方法加上同步代码同步处理)时,只能用 Vector。
3,集合类接口的比较
另外还有几个集合类接口 Set、List,下面是 Collection 和它们的比较Collection对象之间没有指定的顺序,允许重复元素。
Set--对象之间没有指定的顺序,不允许重复元素。
List一一对象之间有指定的顺序,允许重复元素。

import java.util.*;

public class TestSort {
    public static void main(String[] args) {
        ArrayList al = new ArrayList();
        al.add(new Integer(1));
        al.add(new Integer(2));
        al.add(new Integer(3));
        System.out.println(al.toString());
        Collections.sort(al);
        System.out.println(al.toString());
    }
}

Hashtable 也是一种高级数据结构,用以快速检索数据。Hashtable 不仅可以像 Vector样动态存储一系列的对象,而且对存储的每一个对象(称为值)都要安排另一个对象(称为关键字)与之相关联。例如,我们可以在 Hashtable 中存储若干国家的中文和英文名称并且能够通过英文检索出对应的中文名称,这里中文就是值,英文就是关键字。

向 Hashtable 对象中存储数据,使用的是 Hashtableput(Obiect key,Obiect value)方法,从Hashtable 中检索数据,使用 Hashtable.get(Object key)方法。值和关键字都可以是任何类型的非空的对象。

要想成功地从 Hashtable 中检索数据,用作关键字的对象必须正确覆盖了Object.hashCode 方法和 Object.equals 方法。覆盖 Object.equals 道理不难想象,检索数据时必须比较所用关键字是否与存储在 Hashtable 中的某个关键字相等,如果两个关键字对象不能正确判断是否相等,检索是不可能正确的。ObiecthashCode 方法返回一个叫散列码的值,这个值是由对象的地址以某种方式转换来的。内容相同的两个对象,既然是两个对象,地址就不可能一样,所以 Obiect.hashCode 返回的值也不一样。要想两个内容相同的 Obiect子类对象的 hashCode 方法返回一样的散列码,子类必须覆盖 Obiect.hashCode 方法,用于关键字的类,如果它的两个对象用equals 方法比较是相等的,那么这两个对象的 hashcode方法返回值也要一样,所以我们也要覆盖 hashCode 方法。因为 String类已按关键字类的要求覆盖了这两个方法,如果两个 String 对象的内容不相等,它们的hashCode 的返回值也不相等,如果两个 String 对象的内容相等,它们的 hashCode 的返回值也相等,所以,我们在实现自己编写的关键字类的hashCode 方法时,可以调用这个关键字类的 String 类型的成员变量的hashCode 方法来计算关键字类的 hashCode 返回值。注意:StringBuffer 类没有按照关键字类的要求覆盖hashCode 方法,即使两个 StringBuffer 类对象的内容相等,但这两个对象的 hashCode 方法的返回值却不相等。所以,我们不能用StringBuffer 作为关键字类

import java.util.*;

public class HashtableTest {
    public static void main(String[] args) {
        Hashtable numbers = new Hashtable();
        numbers.put(new Mykey("zhangsan",18),new Integer(1));
        numbers.put(new Mykey("lisi",15),new Integer(2));
        numbers.put(new Mykey("wangwu",20),new Integer(3));
        Enumeration e = numbers.keys();
        while (e.hasMoreElements()){
            Mykey key = (Mykey) e.nextElement();
            System.out.println(key.toString()+"==");
            System.out.println(numbers.get(key).toString());
        }
    }
}
public class Mykey {
    private String name;
    private int age;

    public Mykey(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Mykey{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Mykey mykey = (Mykey) o;
        return age == mykey.age &&
                Objects.equals(name, mykey.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
import java.util.*;
import java.io.*;


public class PropertiesFile {
    public static void main(String[] args) {
        Properties settings = new Properties();
        try {
            settings.load(new FileInputStream("c:\\count.txt"));
        }catch (Exception e){
            settings.setProperty("Count",new Integer(0).toString());
        }
        int c = Integer.parseInt(settings.getProperty("Count")) + 1;
        System.out.println("这是本程序第"+c+"次被使用");
        try {
            settings.store(new FileOutputStream("c:\\count.txt"),"This Program is used:");
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值