面试集锦

  1. List与String[]的相互转化
 public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");

        String[] strs = list.toArray(new String[list.size()]);
        for (String s : strs) {
            System.out.println(s);
        }

        list.clear();
        list = Arrays.asList(strs);
        for (String s : list) {
            System.out.println(s);
        }
    }
  1. ==操作
public static void main(String[] args) {
		int a = 2;
		int b = 2;
		String s1 = "你好";
		String s2 = s1;
		System.out.println(a == b);// true
		System.out.println(s1 == s2);// true
	}	
  1. 集合的删除操作
    下面两种方法是否可以完全删除集合中的元素
//1.会跳着删除
public static void delete1(List<String> list) {
		for (int i = 0; i < list.size(); i++) {
			list.remove(i);
		}
		System.out.println(list.size()); //2
		if(!list.isEmpty()){
			for(String element:list){
				System.out.println(element); //b,d
			}
		}
	}

//2.抛出 java.lang.IndexOutOfBoundsException
public static void delete2(List<String> list) {
		int size = list.size();
		for (int i = 0; i < size; i++) {
			list.remove(i);
		}
		System.out.println(list.size());
	}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 如何for循环删除集合中的任意一个元素,且不会出现数组索引越界的异常
 * 1.使用普通for循环,从后往前遍历,倒序删除
 * 2.使用迭代器自身的删除方法,Iterator.remove(),但注意在删除之前要先调用Iterator.next()方法使指针跟随移动
 * @author wh
 * 
 */
public class RemoveList {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("a");
		list.add("c");
		list.add("b");
		list.add("a");
		list.add("b");
		list.add("c");
		
		//remove1(list);
		//remove2(list);
		removwe3(list);
		System.out.println(list);
	}

	// 1.使用普通for循环,倒序删除,从后往前遍历删除
	public static void remove1(List<String> list) {
		for (int i = list.size() - 1; i >= 0; i--) {
			list.remove(i);
		}
	}

	// 2.使用迭代器自己的删除方法
	public static void removwe3(List<String> list) {
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			it.next();
			//在remove之前,必须先next()一下,让指针跟着移动
			it.remove();
		}
	}
}
package com.h.test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * 快速删除List中的重复元素,(保持原有的顺序)
 * a.删除重复元素,且保持原有的顺序
 *   1.使用嵌套两层for循环删除
 *   2.使用Set和List搭配,根据Set.add()方法返回值(只有添加的元素不重复时,为true),将不重复的元素添加进List集合
 *   3.使用List.contatins()方法判断是否包含重复元素,倒进倒出
 * b.删除重复元素,不保证顺序
 *   使用Set的构造方法,将List传进构造方法中,会自动去重,在List.addAll(Set)反倒回来  
 * @author wh
 * 
 */
public class ListDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("a");
		list.add("c");
		list.add("b");
		list.add("a");
		list.add("b");
		list.add("c");
		
		long begin = System.currentTimeMillis();
		 //removeDuplicate(list);
		 //removeDuplicate2(list);
		//removeDuplicateWithOrder(list);
		removeDuplicate3(list);
		long end = System.currentTimeMillis();
		System.out.println("执行时间:"+(end-begin));
	}

	// 1.通过循环进行删除
	public static void removeDuplicate(List<String> list) {
		for (int i = 0; i < list.size() - 1; i++) {
			for (int j = i + 1; j < list.size(); j++) {
				if (list.get(j).equals(list.get(i))) {
					list.remove(j);// 注意,这里必须删除的是j,而不是i,i是作为内层循环的参照元素
				}
			}
		}
		System.out.println(list);
	}

	// 2.通过HashSet删除,元素的顺序会被打乱
	public static void removeDuplicate2(List<String> list) {
		Set<String> set = new HashSet<>(list);
		list.clear();
		list.addAll(set);
		System.out.println(list);
	}

	// 3.去重,并保持顺序
	public static void removeDuplicateWithOrder(List<String> list) {
		Set<String> set = new HashSet<>();
		List<String> newList = new ArrayList<>();
		for (Iterator<String> it = list.iterator(); it.hasNext();) {
			String element = it.next();
			if (set.add(element)) {
				newList.add(element);
			}
		}
		list.clear();
		list.addAll(newList);
		System.out.println(list);
	}

	// 4.list.contains()
	public static void removeDuplicate3(List<String> list) {
		List<String> newList = new ArrayList<>();
		for (Iterator<String> it = list.iterator(); it.hasNext();) {
			String element = it.next();
			if (!newList.contains(element)) {
				newList.add(element);
			}
		}
		System.out.println(newList);
	}
}

package com.h.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * List在遍历的时候能否同时做删除操作? 如果要删除的元素在集合中没有重复,则删除该元素没有问题; 否则删除有重复存在的元素,只会删除第一个
 * 或者干脆就抛出"java.util.ConcurrentModificationException"并发修改异常(通常都会抛出该异常)
 * 
 * @author wh
 * 
 */
public class ListDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("c");
		list.add("c");

		//remove1(list);
		// remove2(list);
		remove3(list);
	}

	// 1.使用普通for循环进行删除
	public static void remove1(List<String> list) {
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).equals("c")) {
				list.remove(i);
			}
		}
		System.out.println(list);
	}

	// 2.使用增强for循环
	public static void remove2(List<String> list) {
		for (String string : list) {
			if ("c".equals(string)) {
				list.remove(string);
			}
		}
		System.out.println(list);
	}

	// 3.使用迭代器进行删除
	public static void remove3(List<String> list) {
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			String element = it.next();
			if ("c".equals(element)) {
				it.remove(element);
			}
		}
		System.out.println(list);
	}
}
  1. Map
package com.h.collection;

import java.util.HashMap;
import java.util.Map;

public class TestMap {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Map<String, String> map1 = new HashMap<String, String>();
		Map<String, Map<String, String>> map2 = new HashMap<String, Map<String, String>>();
		map1.put("ak1", "av1");
		map2.put("m", map1);
		map1.put("ak2", "av2");
		for (Map.Entry<String, Map<String, String>> entry : map2.entrySet()) {
			Map<String, String> map = entry.getValue();
			String key = entry.getKey();
			System.out.println("key=" + key);
			for (Map.Entry<String, String> en : map.entrySet()) {
				System.out.println("key=" + en.getKey());
				System.out.println("value=" + en.getValue());
			}
		}
	}
}

打印结果:
key=ak1
value=av1
key=ak2
value=av2
package com.h.test;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Map的遍历方式
 * 1.获取所有的key的集合 Map.keySet()
 * 2.获取所有的键值对Map.entrySet  Set>,大容量是使用这种方式 
 * @author wh
 * 
 */
public class MapIteration {

	// 第一种:普遍使用,二次取值 Map.keySet()
	public static void iter1(Map<String, String> map) {
		for (String key : map.keySet()) {
			System.out.println("key=" + key + "  value=" + map.get(key));
		}
	}

	// 通过Map.entrySet,推荐使用,尤其是大容量时
	public static void iter2(Map<String, String> map) {
		for (Map.Entry<String, String> entry : map.entrySet()) {
			System.out.println("key=" + entry.getKey() + "  value="
					+ entry.getValue());
		}
	}

	// 通过Map.entrySet使用iterator遍历key和value
	public static void iter3(Map<String, String> map) {
		Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<String, String> entry = it.next();
			System.out.println("key=" + entry.getKey() + "  value="
					+ entry.getValue());
		}
	}

	// 通过Map.values()遍历所有的value,但不能遍历key
	public static void iter4(Map<String, String> map) {
		for (String value : map.values()) {
			System.out.println(value);
		}
	}
}
  1. 引用传递还是值传递?
package com.h.test;

public class ReferenceTest {

	public static void main(String[] args) {
		int i = 0;
		i++;
		inc(i);
		System.out.println(i);//1
	}

	public static void inc(int num) {
		num++;
	}
}
  1. 字符串反转操作
package com.h.test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class StringReverse {
	/**
	 * 使用字符缓存,实现字符数组所有元素的顺序前后颠倒
	 * @param arr 目标字符数组
	 */
	public static void swap1(char[] arr) {
		char temp;
		int length = arr.length;
		for (int i = 0; i < length / 2; i++) {
			temp = arr[i];
			arr[i] = arr[length - 1 - i];
			arr[length - 1 - i] = temp;
		}
	}

	/**
	 * 将字符数组指定范围内的元素前后颠倒
	 * 
	 * @param arr
	 * @param begin 开始索引
	 * @param end   结束索引
	 */
	public static void swap2(char[] arr, int begin, int end) {
		char temp;
		while (begin < end) {
			temp = arr[begin];
			arr[begin] = arr[end];
			arr[end] = temp;
			begin++;
			end--;
		}
	}

	public static String reverse2(String str) {
		char[] arr = str.toCharArray();
		swap2(arr, 0, arr.length - 1);

		int begin = 0;
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] == ' ') {
				swap2(arr, begin, i - 1);
				begin = i + 1;
			}
		}

		return new String(arr);
	}

	public static String reverse3(String str) {
		char[] arr = str.toCharArray();

		if (str.contains(" ")) {
			StringBuilder sb = new StringBuilder();
			String[] strs = str.split(" ");
			for (int i = strs.length - 1; i >= 0; i--) {
				System.out.println(strs[i]);
				if (i == 0) {
					sb.append(strs[i]);
				} else {
					sb.append(strs[i] + " ");
				}
			}
			return sb.toString();
		} else {
			swap2(arr, 0, arr.length - 1);
			return new String(arr);
		}
	}

	// 使用JDK自带的工具类
	public static void reverse4(String str) {
		String[] strs = str.split(" ");
		List<String> list = Arrays.asList(strs);
		Collections.reverse(list);
		for (String string : list) {
			System.out.println(string);
		}
	}

	// 使用异或操作 x^=y;x=x^y;
	public static String reverse5(String str) {
		char[] arr = str.toCharArray();
		int begin = 0;
		int end = arr.length - 1;
		while (begin < end) {
			arr[begin] ^= arr[end];
			arr[end] ^= arr[begin];
			arr[begin] ^= arr[end];
			begin++;
			end--;
		}
		return new String(arr);
	}

	// 使用递归 recursive
	public static String reverse6(String str) {
		if (str.length() == 1) {
			return str;
		} else {
			return reverse6(str.substring(1)) + str.charAt(0);
		}
	}

	// 使用StringBuilder
	public static String reverse1(String str) {
		StringBuilder sb = new StringBuilder();
		for (int i = str.length() - 1; i >= 0; i--) {
			sb.append(str.charAt(i));
		}
		return sb.toString();
	}
}
  1. 字符串的连接操作
package com.h.test;

public class StringTest {

	public static void operate(StringBuffer a, StringBuffer b) {
		a.append(b);
		b = a;
	}

	public static void operate(String a, String b) {
		a += b;
		b = a;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		StringBuffer a = new StringBuffer("A");
		StringBuffer b = new StringBuffer("B");

		String x = "a";
		String y = "b";

		operate(a, b);
		operate(x, y);

		System.out.println(a + "---" + b);//AB---B
		System.out.println(x + "---" + y);//a---b
	}

}
  1. 常量池
package com.h.test;

public class AutoUnboxingTest {
	public static void main(String[] args) {
		Integer a = new Integer(3);//每次new都会在堆中创建新对象
		Integer b = 3;//将3自动装箱成Integer类型,不会创建新对象,直接获取常量池中的[-128,127]
		int c = 3;
		Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
		System.out.println(a == b);//false,两个引用不是指向同一个对象
		System.out.println(a == c);//true a自动拆箱成int类型再和c比较,比较的值
		System.out.println(f1 == f2);//true 100在常量池中
		System.out.println(f3 == f4);//false 不在常量池中,自动装箱Integer.valueOf()
	}
}
  1. 打印文件夹目录
    要求:给定一个目录,打印出该目录包含的目录或者文件的结构来,文件和其父目录之间通过缩进来表示父子关系。

package com.h.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Stack;
 
public class PrintFile {
    private static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) {
        File f = new File("D:/a");
        print2(f, new FileNameFilter() {
            @Override
            public Boolean accept(String filaName) {
                return true;
            }
        });
        System.out.println("=================================");
        print(f, new FileNameFilter() {
            @Override
            public Boolean accept(String filaName) {
                return true;
            }
        },-2,'-');

        System.out.println(sb);
    }

    /**
     * 循环打印文件夹目录结构
     * 递归方式
     a
     --b
     ----d
     ------f.txt
     ------g.txt
     ----e
     ------h.txt
     --c
     ----j.txt
     * @param file 文件目录
     * @param fileNameFilter 文件名称过滤器
     * @param charsToLeft 距离左边的空白或分隔符数目
     * @param spanChar 空白字符
     */
    public static void print(File file,FileNameFilter fileNameFilter,int charsToLeft,char spanChar){
        if (null == file){
            return;
        }
        charsToLeft += 2;
        if (file.isFile()){
            if (fileNameFilter.accept(file.getName())){
                for (int i=0;i<charsToLeft;i++){
                    sb.append(spanChar);
                }
                sb.append(file.getName() + "\r\n");
            }
        }

        if (file.isDirectory()){
            for (int i=0;i<charsToLeft;i++){
                sb.append(spanChar);
            }
            sb.append(file.getName() + "\r\n");
            File[] files = file.listFiles();
            if (null != files){
                for (File f:files) {
                    print(f,fileNameFilter,charsToLeft,spanChar);
                }
            }
        }
    }

    /**
     * 循环打印文件夹目录结构
     * 非递归方式,使用到了Stack
     * 如: $标示目录 层级:文件名
     0:a$
     --1:c$
     ----2:j.txt
     --1:b$
     ----2:e$
     ------3:h.txt
     ----2:d$
     ------3:g.txt
     ------3:f.txt
     * @param file
     * @return
     */
    public static void print2(File file,FileNameFilter fileNameFilter){
        ArrayList<FileDesc> list = new ArrayList<FileDesc>();
        if (file == null){
            return;
        }

        Stack<File> s1 = new Stack<File>();
        Stack<Integer> s2 = new Stack<Integer>();
        s1.push(file);
        s2.push(0);
        FileDesc fileDesc = null;

        while (!s1.empty()){
            File root = s1.pop();
            Integer index = s2.pop();
            if (root.isFile()){
                if (fileNameFilter.accept(root.getName())){
                    fileDesc = new FileDesc(root.getName(),index);
                    list.add(fileDesc);
                }
            }
            if (root.isDirectory()){
                fileDesc = new FileDesc(root.getName()+"$",index);
                list.add(fileDesc);
                File[] child = root.listFiles();
                if (null == child){
                    continue;
                }
                for (File f:child) {
                    s1.push(f);
                    s2.push(index+1);
                }
            }
        }

        /**
         * 打印输出文件夹目录
         */
        FileDesc fileDes = null;
        int fileIndex = 0;
        for (int i=0;i<list.size();i++){
            fileDes = list.get(i);
            fileIndex = fileDes.getFileIndex();
            if (fileIndex != 0){
                for (int j=0;j<2*fileIndex;j++){
                    System.out.print("-");
                }
            }
            System.out.println(list.get(i));
        }
    }
}

你可能感兴趣的:(Utils)