• java字符串,数组,集合框架重点


    1.字符串的字面量是否自动生成一个字符串的变量?

    String  str1  =  “abc”;

    Sring  str2  =   new String (“abc”);

    对于str1:Jvm在遇到双引号时会创建一个String对象,该String对象代表的值是abc,实际上,在创建该对象之前会在String对象池中搜索该字符串对象是否已经被创建,如果已经被创建,就直接返回一个字符串的引用,否则先创建再返回一个引用。

    对于str2:需要的额外的工作是:会创建一个新的的string对象,通过new关键字来实现,并且返回一个引用给str2.

    Str1==str2会返回false,因为指向的并不是同一个引用。

    equals方法会进行字符序列的比较,则会返回true.

    2.字符串对象池的作用是什么?

    java虚拟机在启动的时候会实例化9个对象池,用来存储8种基本数据类型的包装类对象和String对象。

    作用:避免频繁的创建和撤销对象而影响系统的性能。

    例子:

     1 package test;
     2 
     3 import java.util.HashSet;
     4 
     5 class Dog{
     6 
     7 public Dog(String name, int age) {
     8 
     9 super();
    10 
    11 this.name = name;
    12 
    13 this.age = age;
    14 
    15 }
    16 
    17 private String name;
    18 
    19 private int age;
    20 
    21 private static HashSet<Dog> pool = new HashSet<Dog>();
    22 
    23 //使用对象池得到对象的方法
    24 
    25 public static Dog newInstance(String name,int age){
    26 
    27 for(Dog dog :pool){
    28 
    29 if(dog.name.equals(name)&&dog.age==age){
    30 
    31 return dog;
    32 
    33 }
    34 
    35 }
    36 
    37 //否则实例化一个新的dog
    38 
    39 Dog dog = new Dog(name,age);
    40 
    41 pool.add(dog);
    42 
    43 return dog;
    44 
    45 }
    46 
    47 }
    48 
    49 public class Main {
    50 
    51 public static void main(String[] args) {
    52 
    53 Dog dog1 = Dog.newInstance("xiaobai",1);
    54 
    55 Dog dog2 = Dog.newInstance("xiaobai", 1);
    56 
    57 Dog dog3 = new Dog("xiaobai",1);
    58 
    59 System.out.println(dog1==dog2);
    60 
    61 System.out.println(dog1==dog3);
    62 
    63 }
    64 
    65 }

    本质理解:如果调用了new方法,则返回false,因为对象有了新的引用,如果没有调用new方法,就引用的是同一个对象,则返回true.

    3.StringBufferStringBuilder的区别和应用场景?

    javaString对象是不变性,只能被创建,但是不能改变其中的值。

     1 Demo1:
     2 
     3 package test;
     4 
     5 public class Main {
     6 
     7 public static void main(String[] args) {
     8 
     9 String a  = "a";
    10 
    11 String b  = "b";
    12 
    13 String c = "c";
    14 
    15 //采用这种方式,可以创建5个对象
    16 
    17 String abc = a+b+c;
    18 
    19 //使用stringbuffer可以解决性能问题
    20 
    21 //如果要保证是线程安全的,用stringbuilder
    22 
    23 StringBuffer sb = new StringBuffer();
    24 
    25 sb.append(a);
    26 
    27 sb.append(b);
    28 
    29 sb.append(c);
    30 
    31 }
    32 
    33 }
    34 
    35 Demo2:
    36 
    37 1 String s = "abcd";
    38     2 s = s+1;
    39     3 System.out.print(s);// result : abcd1

    首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说 String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多低。

     StringBufferStringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。

    1 Demo3:
    2 
    3 1 String str = “This is only a” + “ simple” + “ test”;
    4 2 StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

    你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:

    1 String str = “This is only a” + “ simple” + “test”;

    其实就是:

    String str = “This is only a simple test”;
    
    所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:
    
    string str2 = “This is only a”;
    
    String str3 = “ simple”;
    
    String str4 = “ test”;
    
    String str1 = str2 +str3 + str4;

    这时候JVM会规规矩矩的按照原来的方式去做。

    Demo4:

    StringBuilder与 StringBuffer

        StringBuilder:线程非安全的

        StringBuffer:线程安全的

      当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证 StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不 用StringBuffer的,就是速度的原因。

    4.如何输出反转后的字符串?

    三种方式的实现:

     1 package test;
     2 
     3 public class Main {
     4 
     5 public static void main(String[] args) {
     6 
     7 String s = "hello world";
     8 
     9 for(int i =s.length();i>0;i--){
    10 
    11 System.out.print(s.charAt(i-1));
    12 
    13 }
    14 
    15 System.out.println();
    16 
    17 System.out.println("--------------");
    18 
    19 char[] array = s.toCharArray();
    20 
    21 for(int i = array.length;i>0;i--){
    22 
    23 System.out.print(array[i-1]);
    24 
    25 }
    26 
    27 System.out.println();
    28 
    29 System.out.println("--------------");
    30 
    31         StringBuffer buff = new StringBuffer(s);
    32 
    33         System.out.println(buff.reverse().toString());
    34 
    35 }
    36 
    37 }

    5.如何利用指定的字符集创造String对象?

    不论是字符串的字面量,还是用String的构造方法创造字符串对象,都不会指定特定的字符集。平台的默认字符集是GBK或者GB2312,当我们用输入法输入中文后,这些中文的默认编码是GBK,但是JVM在编译的时候会按照unicode进行重新的编码。

    利用特定的字符集进行编码:

     1 package test;
     2 
     3 import java.io.UnsupportedEncodingException;
     4 
     5 public class Main {
     6 
     7 public static void main(String[] args) throws UnsupportedEncodingException {
     8 
     9 String s = "哈哈哈";
    10 
    11 String b = new String(s.getBytes(),"GBK");
    12 
    13 String c  = new String(s.getBytes(),"UTF-8");
    14 
    15 System.out.println(b);
    16 
    17 System.out.println(c);
    18 
    19  
    20 
    21 }
    22 
    23 }
    24 
    25 结果:哈哈哈  ??????

    解释:实际上是对原有的字符串先转换为字节数组,然后用一种新的编码方法进行二次编码。

    6.如何理解数组在java中作为一个类?

    数组属于引用类型,每一个数组实例都是一个对象,这些对象同属于一个类。

    java数组的实质是一个类,该类还保存了数据类型的信息。该类通过成员变量的形式保存数据,并且通过[],使用下标来访问这些数据,在处理基本数据类型时,数组保存的是变量的值,如果初始化,系统为之初始化为0;处理引用类型的数据时数组保存的书数据的引用,默认初始化为null.

    7.new Object[5]语句是否创建了5个对象?

    并没有创建5个对象,只是开辟了存放五个对象的内存空间。

    Object[] objarr = new Object[5];

    创建一个存储object的数组,长度为5,这5个元素的值都为null,只有为这些元素分别赋予了具体的对象,才会使得元素指定特定的引用。

     

    8.二维数组的长度是否固定?

    实质:先创建一个一维数组,然后该数组的元素再引用另外一个一维数组,在使用二维数组时,通过两个中括号来访问每一层维度的引用,直到访问到最后的数据。

    二维数组的长度没必要去指定,他们的长度是各异的。

    Int[][] arr = new int[3][];

    第一维的长度是固定的为3,但是第二维的长度却不固定,可以变。

    9.深拷贝和浅拷贝?

    浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制

    深拷贝:对象,对象内部的引用均复制

    10.什么是集合?

    集合代表了一种底层的机构,用来拓展数组的功能,它的每一种形式代表了某一种数据结构。

    Set:无序存放,不允许重复,可以存放不同类型的对象

    List:有序存放,允许重复,可以存放不同类型的对象

    SoretdSet:排好序列set

    sortedMap:排好序列的map

    注意:所有的集合实现类都只能存放对象,如果存放基本数据类型的数据,则需要使用包装类。

    11.java中的迭代器是什么?

    迭代器模式又称为游标模式,提供一种方法,访问一个容器对象中的元素,但是隐藏对象的内部细节。

    实际上,迭代器就是一个接口Iterator,实现了该接口的类是可迭代类。

    一个列子:

     1 package test;
     2 
     3 import java.util.ArrayList;
     4 
     5 import java.util.Iterator;
     6 
     7 import java.util.List;
     8 
     9 public class Main {
    10 
    11 public static void main(String[] args){
    12 
    13 List<String> list = new ArrayList<String>();
    14 
    15 list.add("hello");
    16 
    17 list.add("world");
    18 
    19 Iterator<String> it = list.iterator();
    20 
    21 //hasnext判断是否有下个元素,next()用于输出下一个元素
    22 
    23 while(it.hasNext()){
    24 
    25 System.out.println(it.next());
    26 
    27 }
    28 
    29 }
    30 
    31 }

    12.java中的比较器是什么?

    当用户自己自定义了一个类,这个类需要进行比较,这个时候就要使用到comparablecomparator接口。

    Comparable进行比较类需要实现的接口,仅仅包含一个CompareTo()方法,(在类中需要重写该方法)只有一个参数,返回值类型为int型,如果该返回值大于0,表示本对象大于参数对象,如果小于0,表示本对象小于参数对象,等于0,则相等。

     

    一个例子:

     1 package test;
     2 
     3 public class User implements Comparable{
     4 
     5 public User(String name, int age) {
     6 
     7 super();
     8 
     9 this.name = name;
    10 
    11 this.age = age;
    12 
    13 }
    14 
    15 public String getName() {
    16 
    17 return name;
    18 
    19 }
    20 
    21 public void setName(String name) {
    22 
    23 this.name = name;
    24 
    25 }
    26 
    27 public int getAge() {
    28 
    29 return age;
    30 
    31 }
    32 
    33 public void setAge(int age) {
    34 
    35 this.age = age;
    36 
    37 }
    38 
    39 @Override
    40 
    41 public int compareTo(Object o) {
    42 
    43 // TODO Auto-generated method stub
    44 
    45 return this.age-((User) o).getAge();
    46 
    47         //如果当前类的age大于参数的age 返回大于0的数
    48 
    49 //相等则返回0
    50 
    51 }
    52 
    53 private String name;
    54 
    55 private int age;
    56 
    57 }
    58 
    59 主函数测试:
    60 
    61 package test;
    62 
    63  
    64 
    65 public class Main {
    66 
    67 public static void main(String[] args){
    68 
    69     User   user1 = new User("hello",10);
    70 
    71     User  user2 = new User("wwww",20);
    72 
    73     if(user1.compareTo(user2)<0){
    74 
    75      System.out.println("user1's age is smaller");
    76 
    77     }else{
    78 
    79      System.out.println("equal");
    80 
    81     }
    82 
    83 }
    84 
    85 }

    comparator也是一个接口,它的实现者被称为比较器,包含一个compare()方法,有两个参数,comparator不会被集合元素实现类所实现,而是单独实现或者是用匿名内部类实现。

    一个例子:

    首先自己定义一个比较器,用于比较特定的属性:

      1 package test;
      2 
      3 import java.util.Comparator;
      4 
      5 public class MyComparator implements Comparator {
      6 
      7  
      8 
      9 @Override
     10 
     11 public int compare(Object o1, Object o2) {
     12 
     13          User u1 = (User)o1;
     14 
     15          User u2 = (User)o2;
     16 
     17          return u1.getAge()-u2.getAge();
     18 
     19 }
     20 
     21 }
     22 
     23 实体类:
     24 
     25 package test;
     26 
     27 public class User{
     28 
     29 public User(String name, int age) {
     30 
     31 super();
     32 
     33 this.name = name;
     34 
     35 this.age = age;
     36 
     37 }
     38 
     39 public String getName() {
     40 
     41 return name;
     42 
     43 }
     44 
     45 public void setName(String name) {
     46 
     47 this.name = name;
     48 
     49 }
     50 
     51 public int getAge() {
     52 
     53 return age;
     54 
     55 }
     56 
     57 public void setAge(int age) {
     58 
     59 this.age = age;
     60 
     61 }
     62 
     63  
     64 
     65 private String name;
     66 
     67 private int age;
     68 
     69 }
     70 
     71 测试函数:
     72 
     73 package test;
     74 
     75 public class Main {
     76 
     77 public static void main(String[] args) {
     78 
     79 User user1 = new User("hello", 10);
     80 
     81 User user2 = new User("wwww", 20);
     82 
     83 int res;
     84 
     85     MyComparator comparator = new MyComparator();
     86 
     87     res= comparator.compare(user1, user2);
     88 
     89     if(res>0){
     90 
     91      System.out.println("user1's age bigger");
     92 
     93     }else if(res<0){
     94 
     95      System.out.println("user2's age bigger");
     96 
     97     }else{
     98 
     99      System.out.println("equal");
    100 
    101     }
    102 
    103 }
    104 
    105 }

    13.Vectorarraylist的区别?

    都是List接口的实现类,都代表链表形式的数据结构。

    Vector是线程安全的,保证了线程安全,但是此时的执行效率会低一些,如果要求执行效率则使用arrayList.在使用方法上二者基本一样。

    14.HashTableHashMap的区别?

    二者在保存元素都是无序的。

    1>HashTable的方法是线程同步的hashmap不能同步,在多线程的情况下要使用HashTable.

    2>HashTable 不允许null值,keyvalue都不允许。HashMap允许null值,keyvalue都允许。

    3>HashTable有一个contains方法,功能和containsvalue功能一样

    4>HashTable使用Enumeration遍历,HashMap使用Iterator进行变量。

    5>HashTable 中的hash数组的初始化大以及其增长方式不同

    6>哈希值的使用不同,hashTable直接使用对象的HashCode,HashMap会重新计算哈希值。

    如果没有要求是线程安全的,推荐使用hashMap,更符合java集合框架的设计思路。

    15.集合使用泛型单来什么好处?

    集合使用泛型后可以达到元素类型明确的目的,避免了手动类型转换的过程,同时也让开发者明确了容器保存的是什么类型的数据。这样,在每次从集合中取得的数据就不用每次取出一个进行类型的转换。需要注意的是,java的泛型是停在编译层的,jvm在对待泛型数据时,会依然把他们当成是object来处理,只是jvm会在底层帮助开发者完成类型的转换。

    16.如何把集合对象中的元素进行排序?

    vectorarraylist linkedlist本身不可以进行元素的排序。

    可以使用java.utils.collections类下的sort方法进行排序。

    如果列表中的全部是相同类型的数据元素,并且这个类实现了comparable接口,可以简单调用sort方法,如果没有实现comparator,就要传递一个comparator的实例作为第二个参数。

    一个例子:

    Student 类要实现Comparable接口,重写compareTo方法

      1 package test;
      2 
      3 public class Student implements Comparable<Student> {
      4 
      5 @Override
      6 
      7 public String toString() {
      8 
      9 return "Student [name=" + name + ", age=" + age + "]";
     10 
     11 }
     12 
     13 public String getName() {
     14 
     15 return name;
     16 
     17 }
     18 
     19 public void setName(String name) {
     20 
     21 this.name = name;
     22 
     23 }
     24 
     25 public int getAge() {
     26 
     27 return age;
     28 
     29 }
     30 
     31 public void setAge(int age) {
     32 
     33 this.age = age;
     34 
     35 }
     36 
     37 public Student(String name, int age) {
     38 
     39 super();
     40 
     41 this.name = name;
     42 
     43 this.age = age;
     44 
     45 }
     46 
     47 @Override
     48 
     49 public int compareTo(Student o) {
     50 
     51         if(this.age>o.age){
     52 
     53          return 1;
     54 
     55         }else if(this.age<o.age){
     56 
     57          return -1;
     58 
     59         }else{
     60 
     61          return 0;
     62 
     63         }
     64 
     65 }
     66 
     67 private String name;
     68 
     69 private int age;
     70 
     71  
     72 
     73 }
     74 
     75 测试类中按照三种方式去排序:
     76 
     77 package test;
     78 
     79 import java.util.ArrayList;
     80 
     81 import java.util.Collections;
     82 
     83 import java.util.Comparator;
     84 
     85 import java.util.Iterator;
     86 
     87 import java.util.List;
     88 
     89 public class Main {
     90 
     91 @SuppressWarnings("unchecked")
     92 
     93 public static void main(String[] args) {
     94 
     95 List<Student> list = new ArrayList<Student>();
     96 
     97 list.add(new Student("admin", 20));
     98 
     99 list.add(new Student("dddd", 30));
    100 
    101 list.add(new Student("wwww", 60));
    102 
    103 System.out.println("default order...");
    104 
    105 // 默认的顺序
    106 
    107 @SuppressWarnings("rawtypes")
    108 
    109 Iterator it = list.iterator();
    110 
    111 while (it.hasNext()) {
    112 
    113 System.out.println(it.next());
    114 
    115 }
    116 
    117 System.out.println("desc order...");
    118 
    119 // 降序排序
    120 
    121 @SuppressWarnings("rawtypes")
    122 
    123 Comparator comp = Collections.reverseOrder();
    124 
    125 Collections.sort(list, comp);
    126 
    127 @SuppressWarnings("rawtypes")
    128 
    129 Iterator it1 = list.iterator();
    130 
    131 while (it1.hasNext()) {
    132 
    133 System.out.println(it1.next());
    134 
    135 }
    136 
    137 System.out.println("by name order...");
    138 
    139  
    140 
    141 // 按照名字进行排序
    142 
    143 Collections.sort(list, new Comparator<Student>() {
    144 
    145 @Override
    146 
    147 public int compare(Student o1, Student o2) {
    148 
    149 return o1.getName().compareTo(o2.getName());
    150 
    151 }
    152 
    153 });
    154 
    155 Iterator it2 = list.iterator();
    156 
    157 while (it2.hasNext()) {
    158 
    159 System.out.println(it2.next());
    160 
    161 }
    162 
    163 }
    164 
    165 }

     

  • 相关阅读:
    char*,const char*和string 互转
    创建txt文件,并且写入内容
    monit 命令详解(monit)
    monit 配置详解(monitrc)
    nginx 配置详解(./configure)
    nginx 配置详解(nginx.conf)
    获取并检查系统负载CPU内存磁盘网络
    构建Zookeeper集群(zkcluster) ~一篇文章玩转zk集群^.^
    安装Zookeeper到Linux
    使用kubeadm搭建Kubernetes(K8S)集群
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/5729990.html
Copyright © 2020-2023  润新知