您的位置:首页 > 职场人生

一道面试题引发的集合、数组、列表之间相互转换

2016-09-15 17:06 651 查看
一.面试题:写java方法找出List<Integer>序列中第二个小的值?如列表{4,5,8,3,3,9,7,56,46,42,65,8,44,9},找到4.方法1:自定义数组进行排序,在去重这道题分两步:①排序②去重
package practice02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

/**
* int[] arr = { 4, 5, 8, 3, 3, 9, 7, 56, 46, 42, 65, 8, 44, 91 };
*
* @Blog http://blog.csdn.net/yan_yuhan * @author Jason
* @2016年9月12日 下午12:05:56
*/
public class CollectionToArray1 {
public static void main(String[] args) {
// 定义list集合
List<Integer> list = new ArrayList<>();
// 键盘录入数据
intputData(list);
// 查询第二个小的值
method1(list);
}

/**
* 这是键盘录入任意数据,并存储到集合中的方法
*/
private static void intputData(List<Integer> list) {
Scanner sc = new Scanner(System.in);
// 定义布尔标记
boolean flag = false;
int firstData = 1;
do {
System.out.println("请输入第" + firstData + "个数据:");
String data = sc.nextLine();
// 把数据存储到集合中
list.add(Integer.parseInt(data));
System.out.println("是否继续录入数据?y/n");
String choice = sc.nextLine();

if (choice.equalsIgnoreCase("n"))
break;
else if(!choice.equalsIgnoreCase("y"))
System.out.println("输入有误,请重新输入:");

firstData++;

} while (!flag);
}

/**
* 这是查询集合中第二个小的值
* 自定义数组,实现排序去重
*/
private static void method1(List<Integer> list) {

// 定义一个长度和集合一样的数组
int[] arr = new int[list.size()];
// 遍历集合并把元素存储到数组中
for (int i = 0; i < list.size(); i++) {
arr[i] = list.get(i);
}
// 对数组排序
Arrays.sort(arr);
// 去重
// 创建新的list集合
List<Integer> list1 = new ArrayList<>();
// 遍历数组并把元素存储到新集合
for (int i = 0; i < arr.length; i++) {
if (!list1.contains(arr[i]))
list1.add(arr[i]);
}
// 集合中的所有元素
System.out.println(list1);

// 在新集合中获取第二个小的元素即可
for (int i = 0; i < list1.size(); i++) {
if (list1.size() >= 2) {
System.out.println("第二个小的数是:" + list1.get(1));
break;
} else if (list1.size() > 0)
System.out.println("最小数是:" + list1.get(i));
else
throw new RuntimeException("集合中没有这样的元素");
}
}
}
方法2和方法3:用Api中的集合转数组的方法实现两种集合转数组的用法:
package practice02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
* 这是集合转数组的用法. 方法2:Object[] toArray()
* 		         方法3:<T> T[] toArray(T[] a)
*
* @Blog http://blog.csdn.net/yan_yuhan * @author Jason
* @2016年9月14日 下午7:31:28
*/
public class CollectionToArray2 {
public static void main(String[] args) {
// 创建集合对象
List<Integer> list = new ArrayList<>();
// 方法1
intputData(list);
method1(list);

// 方法2
method2(list);
}

/**
* 这是键盘录入任意数据,并存储到集合中的方法
*/
private static void intputData(List<Integer> list) {
Scanner sc = new Scanner(System.in);
// 定义布尔标记
boolean flag = false;
// 定义数据的第一个值
int firstData = 1;

do {
System.out.println("请输入第" + firstData + "个数据:");
String data = sc.nextLine();
// 把数据添加到集合中
list.add(Integer.parseInt(data));
System.out.println("是否继续录入数据?y/n");
String choice = sc.nextLine();

if (choice.equalsIgnoreCase("n"))
break;
else if(!choice.equalsIgnoreCase("y"))
System.out.println("输入有误,请重新输入:");

firstData++;

} while (!flag);
}

/**
* 集合转数组的第一种方法
*/
private static void method1(List<Integer> list) {
// 把集合转换成数组
Object[] array = list.toArray();
// 对数组进行排序
Arrays.sort(array);
// 创建新的集合对象
List<Integer> list1 = new ArrayList<>();
// 去重
// 把数组中的数据存储到新的集合中
for (int i = 0; i < array.length; i++) {
// Object类型到Iteger类型,要向下转型
if (!list1.contains((Integer) array[i])) {
list1.add((Integer) array[i]);
}
}
// 输出集合list1的元素
System.out.println(list1);

/**
* 这是查询集合中第二个小的值
*/
for (int i = 0; i < list1.size(); i++) {
if (list1.size() >= 2) {
System.out.println("第二个小的数是:" + list1.get(1));
break;
} else if (list1.size() > 0)
System.out.println("最小数是:" + list1.get(i));
else
throw new RuntimeException("集合中没有这样的元素");
}
}

/**
* 集合转数组的第二种方法
*/
private static void method2(List<Integer> list) {
// 在把集合中所有元素转换成数组,返回的数组和运行时数组一样
Integer[] array = list.toArray(new Integer[list.size()]);
// 对数组进行排序
Arrays.sort(array);
// 创建新的集合
List<Integer> list1 = new ArrayList<>();

// 遍历数组,把数组中的数据存储到新集合中
for (Integer integer : array) {
if (!list1.contains(integer))
list1.add(integer);
}

/**
* 这是查询集合中第二个小的值
*/
for (int i = 0; i < list1.size(); i++) {
if (list1.size() >= 2) {
System.out.println("第二个小的数是:" + list1.get(1));
break;
} else if (list1.size() > 0)
System.out.println("最小数是:" + list1.get(i));
else
throw new RuntimeException("集合中没有这样的元素");
}
}
}
方法4:用set集合排序,用map集合存储
package practice02;

import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

/**
* int[] arr = { 4, 5, 8, 3, 3, 9, 7, 56, 46, 42, 65, 8, 44, 91 };
* 这是利用set集合排序,map集合取值的方法
*
* @Blog http://blog.csdn.net/yan_yuhan * @author Jason
* @2016年9月12日 下午12:05:56
*
*/
public class T3 {
public static void main(String[] args) {
method();
}

/**
* 这是利用set集合
*/
private static void method() {
// 定义一个set集合
Set<Integer> set = new TreeSet<>();
// 定义一个map集合
Map<Integer, Integer> map = new TreeMap<>();
Scanner sc = new Scanner(System.in);
// 定义布尔标记
boolean flag = false;
int firstData = 1;

do {
System.out.println("请输入第" + firstData + "个数据:");
String data = sc.nextLine();
// 把数据存储到set集合中,排好序
set.add(Integer.parseInt(data));
System.out.println("是否继续录入数据?y/n");
String choice = sc.nextLine();

if (choice.equalsIgnoreCase("n"))
break;
else if(!choice.equalsIgnoreCase("y"))
System.out.println("输入有误,请重新输入:");

firstData++;
} while (!flag);

/**
* 把set中的元素存储到map集合中
* 自定义键的值
*/

int keyValue = 1;
//把set集合中的值存储到map集合中
for (Integer i : set) {
map.put(keyValue++, i);
}

//获取键值的集合
Set<Integer> st = map.keySet();

//遍历集合渠道第二小的值
for (Integer key : st) {
//集合中录入元素大于2时候,取到第二小的值
if (key>= 2) {
System.out.println("最小数是:" + map.get(2));
break;
}
//如果集合中只有一个元素那么取到第一个值为最小值
else if(key>0)
System.out.println("最小数是:" + map.get(key));
else
//都不符合要求,则抛出异常
throw new RuntimeException("集合中没有这样的元素");
}
}
}
方法5.方法6(最简洁)把数据直接存储到set集合中,然后创建一个新的list集合,把set集合所有元素直接添加到list集合中,然后获取第二小的值。
package practice02;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

/**
* 这是集合转数组的用法. 方法2:Object[] toArray() 方法3:<T> T[] toArray(T[] a)
*
* @Blog http://blog.csdn.net/yan_yuhan * @author Jason
* @2016年9月14日 下午7:31:28
*/
public class CollectionToArray4 {
public static void main(String[] args) {
// 定义一个set集合
Set<Integer> set = new TreeSet<>();
// 录入数据,并存储到set集合中排序
intputData(set);
// 获取第二小的值
method1(set);
}

/**
* 这是键盘录入任意数据,并存储到集合中的方法
*/
private static void intputData(Set<Integer> set) {
Scanner sc = new Scanner(System.in);
// 定义布尔标记
boolean flag = false;
// 定义数据的第一个值
int firstData = 1;

do {
System.out.println("请输入第" + firstData + "个数据:");
String data = sc.nextLine();
// 把数据添加到集合中
set.add(Integer.parseInt(data));
System.out.println("是否继续录入数据?y/n");
String choice = sc.nextLine();

if (choice.equalsIgnoreCase("n"))
break;
else if (!choice.equalsIgnoreCase("y"))
System.out.println("输入有误,请重新输入:");

firstData++;

} while (!flag);
}

/**
* 这是取出第二小的值
* 1. 可以直接把数据存储到空的set集合,对元素进行排序,然后把set集合全部添加到list集合中,取出第二小的值。
* 2.也可以先把元素存储到list集合中,然后把list集合全部添加到set集合进行排序,清除原来的list集合,然后把set集合元素
* 全部添加到list集合中,获取第二小的值
*/
private static void method1(Set<Integer> set) {
// 创建list集合对象
List<Integer> list = new ArrayList<>();
// 把排好序的set集合所有元素添加到list集合中
list.addAll(set);
// 获取list集合全部数据
System.out.println("list集合元素有:" + list);
// 取出第二小的数
if (list.size() >= 2)
System.out.println("集合中第二小的数是:" + list.get(1));
else if (list.size() > 0)
System.out.println("集合中第二小的数是:" + list.get(0));
else
throw new RuntimeException("集合中没有这样的元素");
}
}

二.集合转数组(API方法)

API中的方法1:<T> T[] toArray(T[] a)比如Integer[] array=list.toArray(new Integer[0])或者Integer[] array=list.toArray(new Integer[list.size()]);API解释:  返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。如果指定的数组能容纳该 collection,则返回包含此 collection 元素的数组。否则,将分配一个具有指定数组的运行时类型和此 collection 大小的新数组。        如果指定的数组能容纳 collection,并有剩余空间(即数组的元素比 collection 的元素多),那么会将数组中紧接 collection 尾部的元素设置为 null。如果此 collection 对其迭代器返回的元素顺序做出了某些保证,那么此方法必须以相同的顺序返回这些元素。假定 x 是只包含字符串的一个已知 collection。以下代码用来将 collection 转储到一个新分配的 String 数组:String[] y = x.toArray(new String[0]); 注意,toArray(new Object[0]) 和 toArray() 在功能上是相同的。参数:a - 存储此 collection 元素的数组(如果其足够大);否则,将为此分配一个具有相同运行时类型的新数组。返回:包含此 collection 中所有元素的数组抛出:ArrayStoreException - 如果指定数组的运行时类型不是此 collection 每个元素运行时类型的超类型NullPointerException - 如果指定的数组为 nullAPI中的方法2:Object[] toArray()比如Object[] listArray = list.toArray();集合转成Object数组类型,取出元素时需要向下转型。数组只能存放相同类型的数据,所以要用泛型进行限定。Object[] toArray()是Collection接口中就有的,那么其子类都应该具有。例如:
package practice02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test01 {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<>();

//输出list集合元素
System.out.println("list集合的元素是:"+list);
System.out.println("list集合的长度:"+list.size());

//把集合转换成数组
String[] listArray =list.toArray(new String[0]);
//输出数组长度
System.out.println("数组的长度:"+listArray.length);
//输出数组的字符串
System.out.println("数组的字符串表达式是:"+Arrays.toString(listArray));
listArray[0]="9";
System.out.println("数组的字符串表达式是:"+Arrays.toString(listArray));
}

}
输出结果:Exception in thread "main" list集合的元素是:[]list集合的长度:0数组的长度:0数组的字符串表达式是:[]java.lang.ArrayIndexOutOfBoundsException: 0at practice02.Test01.main(Test01.java:22)原因:集合长度为0,数组也为0,给数组添加数据会发生数组索引越界异常
package practice02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test01 {
public static void main(String[] args) {
// 创建List集合对象
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
// 输出list集合元素
System.out.println("list集合的元素是:" + list);
System.out.println("list集合的长度:" + list.size());

// 把集合转换成数组
String[] listArray = list.toArray(new String[0]);
// 输出数组长度
System.out.println("数组的长度:" + listArray.length);
// 输出数组的字符串
System.out.println("数组的字符串表达式是:" + Arrays.toString(listArray));
listArray[0] = "9";
listArray[1] = "8";
listArray[2] = "7";
System.out.println("数组的字符串表达式是:" + Arrays.toString(listArray));
}

}
输出结果是:list集合的元素是:[1, 2, 3]list集合的长度:3数组的长度:3数组的字符串表达式是:[1, 2, 3]数组的字符串表达式是:[9, 8, 7]注意:数组的长度小于集合的长度,那么会重新分配一个新的数组。这里集合要用泛型限制,否则会发生转换异常。list集合的底层就是可变数组,长度不够就会创建新的数组进行存储。

三:数组转集合方法

Arrays工具类里面的方法比如:Integer[] arr={1,2,35,4};           List<Integer> asList = Arrays.asList(arr);注意:集合存储的是对象的引用,所以数组必须是包装类型。

四.集合转列表

Collection实现了addAll方法,所有子类都继承了此方法。所以ArrayList、LinkedList、Vector和HashSet、LinkedSet、TreeSet都可把一个集合中的所有元素添加到另一个集合里面,这样就很方便。需要排序先使用Set集合类,要想使用角标时直接把排好序的元素全部放到一个list集合中。这样弥补了List集合类不能排序的缺点,也弥补了set集合没有角标的特点。这样综合使用倒是很实用。
数组到集合,集合在到集合之间就连接起来了。
比如:Integer[] arr={0,8,76,5,2,3,3,0};   List<Integer> asList = Arrays.asList(arr);   Set<Integer> set=new HashSet(asList);

六.总结

1.集合是存储对象的地址引用,所以要用泛型限定。数组只能存储数据类型一致的数据,转为集合时必须是包装类型数据。
2.数组与集合,集合与集合之间是可以相互转换使用的。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息