集合转换

List 与 Array 转换

List 接口提供了 toArray() 方法来返回包含列表元素的 Object 数组:

List<String> list = Arrays.asList("C", "C++", "Java");
Collections.singletonList("test");
Object[] array = list.toArray();

System.out.println(Arrays.toString(array));

不过该函数并不了解元素的类型,可以通过 toArray(T[] a) 来返回指定类型的数组:

List<String> list = Arrays.asList("C", "C++", "Java");
String[] array = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(array));

// 我们还可以传入空数组来让 JVM 自动分配内存
List<String> list = Arrays.asList("C", "C++", "Java");
String[] array = list.toArray(new String[0]);
System.out.println(Arrays.toString(array));

在 Java 8 中我们可以使用 Stream API 来将列表转化为数组:

List<String> list = Arrays.asList("C", "C++", "Java");
String[] array = list.stream().toArray(String[]::new);
System.out.println(Arrays.toString(array));

List<String> list = Arrays.asList("C", "C++", "Java");
String[] array = list.stream().toArray(n -> new String[n]);
System.out.println(Arrays.toString(array));

可以使用 asList 等方法将数组转化为列表:

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arrays));
List<String> list = Arrays.asList(arrays);

List<String> list2 = new ArrayList<String>(arrays.length);
Collections.addAll(list2, arrays);

List 与 Map

Map 转化为 List

Map<String, String> map = new HashMap<>();

// Convert all Map keys to a List
List<String> result = new ArrayList(map.keySet());

// Convert all Map values to a List
List<String> result2 = new ArrayList(map.values());

// Java 8, Convert all Map keys to a List
List<String> result3 = map.keySet().stream()
	.collect(Collectors.toList());

// Java 8, Convert all Map values  to a List
List<String> result4 = map.values().stream()
	.collect(Collectors.toList());

// Java 8, seem a bit long, but you can enjoy the Stream features like filter and etc.
List<String> result5 = map.values().stream()
	.filter(x -> !"apple".equalsIgnoreCase(x))
	.collect(Collectors.toList());

// Java 8, split a map into 2 List, it works!
// refer example 3 below

我们也可以在转化过程中引入流变换操作:

// split a map into 2 List
List<Integer> resultSortedKey = new ArrayList<>();
List<String> resultValues = map.entrySet().stream()
        //sort a Map by key and stored in resultSortedKey
        .sorted(Map.Entry.<Integer, String>comparingByKey().reversed())
        .peek(e -> resultSortedKey.add(e.getKey()))
        .map(x -> x.getValue())
        // filter banana and return it to resultValues
        .filter(x -> !"banana".equalsIgnoreCase(x))
        .collect(Collectors.toList());

resultSortedKey.forEach(System.out::println);
resultValues.forEach(System.out::println);

List 转化为 Map

可以使用 Collectors.toMap 来将某个列表转化为 Map:

// key = id, value - websites
Map<Integer, String> result1 = list.stream().collect(
        Collectors.toMap(Hosting::getId, Hosting::getName));

System.out.println("Result 1 : " + result1);

// key = name, value - websites
Map<String, Long> result2 = list.stream().collect(
        Collectors.toMap(Hosting::getName, Hosting::getWebsites));

System.out.println("Result 2 : " + result2);

// Same with result1, just different syntax
// key = id, value = name
Map<Integer, String> result3 = list.stream().collect(
        Collectors.toMap(x -> x.getId(), x -> x.getName()));

System.out.println("Result 3 : " + result3);

对于可能的键值重复,可以传入第三个 mergeFunction 参数来进行处理:

Map<String, Long> result1 = list.stream().collect(
        Collectors.toMap(Hosting::getName, Hosting::getWebsites,
                (oldValue, newValue) -> oldValue
        )
);

如果需要对列表进行排序等操作,则可以使用中间操作符:

Map result1 = list.stream()
        .sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
        .collect(
                Collectors.toMap(
                        Hosting::getName, Hosting::getWebsites, // key = name, value = websites
                        (oldValue, newValue) -> oldValue,       // if same key, take the old key
                        LinkedHashMap::new                      // returns a LinkedHashMap, keep order
                ));

Links

上一页