Tôi muốn chuyển đổi một mảng thành Set trong Java. Có một số cách rõ ràng để làm điều này (tức là với một vòng lặp) nhưng tôi muốn một cái gì đó gọn gàng hơn, đại loại như:
java.util.Arrays.asList(Object[] a);
Có ý kiến gì không?
Tôi muốn chuyển đổi một mảng thành Set trong Java. Có một số cách rõ ràng để làm điều này (tức là với một vòng lặp) nhưng tôi muốn một cái gì đó gọn gàng hơn, đại loại như:
java.util.Arrays.asList(Object[] a);
Có ý kiến gì không?
Câu trả lời:
Như thế này:
Set<T> mySet = new HashSet<>(Arrays.asList(someArray));
Trong Java 9+, nếu bộ không thể thay đổi là ok:
Set<T> mySet = Set.of(someArray);
Trong Java 10+, tham số kiểu chung có thể được suy ra từ kiểu thành phần mảng:
var mySet = Set.of(someArray);
Arrays.asList
là O (1).
Set<T> mySet = new HashSet<T>();
Collections.addAll(mySet, myArray);
Đó là Bộ sưu tập.add ALL (java.util.Collection, T ...) từ JDK 6.
Ngoài ra: nếu mảng của chúng ta đầy nguyên thủy thì sao?
Đối với JDK <8, tôi sẽ chỉ viết for
vòng lặp rõ ràng để thực hiện gói và bổ trợ trong một lượt.
Đối với JDK> = 8, một tùy chọn hấp dẫn giống như:
Arrays.stream(intArray).boxed().collect(Collectors.toSet());
java.util.Collections.addAll
. Thêm vào đó, tôi sẽ không đề xuất Bộ sưu tập Commons nữa, những gì với nó không được tạo ra và ổi hiện có.
addAll
sẽ là O ( n ).
Với ổi bạn có thể làm:
T[] array = ...
Set<T> set = Sets.newHashSet(array);
new HashSet<T>(Arrays.asList(someArray))
. Xem google.github.io/guava/release/19.0/api/docs/com/google/common/ Kẻ
Java 8:
String[] strArray = {"eins", "zwei", "drei", "vier"};
Set<String> strSet = Arrays.stream(strArray).collect(Collectors.toSet());
System.out.println(strSet);
// [eins, vier, zwei, drei]
Chúng tôi có tùy chọn sử dụng Stream
là tốt. Chúng tôi có thể nhận luồng theo nhiều cách khác nhau:
Set<String> set = Stream.of("A", "B", "C", "D").collect(Collectors.toCollection(HashSet::new));
System.out.println(set);
String[] stringArray = {"A", "B", "C", "D"};
Set<String> strSet1 = Arrays.stream(stringArray).collect(Collectors.toSet());
System.out.println(strSet1);
// if you need HashSet then use below option.
Set<String> strSet2 = Arrays.stream(stringArray).collect(Collectors.toCollection(HashSet::new));
System.out.println(strSet2);
Mã nguồn của Collectors.toSet()
chương trình cho thấy các phần tử được thêm lần lượt vào một HashSet
nhưng một đặc điểm kỹ thuật không đảm bảo nó sẽ là a HashSet
.
"Không có sự đảm bảo nào về loại, tính biến đổi, tính tuần tự hoặc độ an toàn của luồng được đặt lại."
Vì vậy, tốt hơn là sử dụng các tùy chọn sau. Đầu ra là:
[A, B, C, D]
[A, B, C, D]
[A, B, C, D]
Java 9 đã giới thiệu Set.of
phương thức nhà máy tĩnh trả về tập hợp bất biến cho các phần tử được cung cấp hoặc mảng.
@SafeVarargs
static <E> Set<E> of(E... elements)
Kiểm tra các phương pháp nhà máy tĩnh bất biến để biết chi tiết.
Chúng ta cũng có thể có được một bộ bất biến theo hai cách:
Set.copyOf(Arrays.asList(array))
Arrays.stream(array).collect(Collectors.toUnmodifiableList());
Phương thức Collectors.toUnmodifiableList()
bên trong sử dụng Set.of
giới thiệu trong Java 9. Ngoài ra, hãy kiểm tra câu trả lời này của tôi để biết thêm.
Stream.of()
- Tôi không biết cái đó. Một vấn đề nhỏ về Collectors.toSet()
: bạn nói rằng thông số kỹ thuật không đảm bảo thêm từng yếu tố một, nhưng đó là ý nghĩa của nó: "tích lũy ... thành một cái mới Set
". Và nó dễ đọc hơn - rất phù hợp với suy nghĩ của tôi, nếu bạn không cần sự đảm bảo về loại cụ thể, tính dễ biến đổi, tính tuần tự và an toàn luồng.
HashSet
. Nó chỉ đảm bảo rằng nó sẽ là một Set
và đó là những gì tôi muốn nói. Hy vọng tôi làm rõ nó.
Sau khi bạn làm Arrays.asList(array)
bạn có thể thực hiệnSet set = new HashSet(list);
Đây là một phương pháp mẫu, bạn có thể viết:
public <T> Set<T> GetSetFromArray(T[] array) {
return new HashSet<T>(Arrays.asList(array));
}
Trong Bộ sưu tập Eclipse , những điều sau đây sẽ hoạt động:
Set<Integer> set1 = Sets.mutable.of(1, 2, 3, 4, 5);
Set<Integer> set2 = Sets.mutable.of(new Integer[]{1, 2, 3, 4, 5});
MutableSet<Integer> mutableSet = Sets.mutable.of(1, 2, 3, 4, 5);
ImmutableSet<Integer> immutableSet = Sets.immutable.of(1, 2, 3, 4, 5);
Set<Integer> unmodifiableSet = Sets.mutable.of(1, 2, 3, 4, 5).asUnmodifiable();
Set<Integer> synchronizedSet = Sets.mutable.of(1, 2, 3, 4, 5).asSynchronized();
ImmutableSet<Integer> immutableSet = Sets.mutable.of(1, 2, 3, 4, 5).toImmutable();
Lưu ý: Tôi là người đi làm cho Bộ sưu tập Eclipse
Nhanh chóng: bạn có thể làm:
// Fixed-size list
List list = Arrays.asList(array);
// Growable list
list = new LinkedList(Arrays.asList(array));
// Duplicate elements are discarded
Set set = new HashSet(Arrays.asList(array));
và để đảo ngược
// Create an array containing the elements in a list
Object[] objectArray = list.toArray();
MyClass[] array = (MyClass[])list.toArray(new MyClass[list.size()]);
// Create an array containing the elements in a set
objectArray = set.toArray();
array = (MyClass[])set.toArray(new MyClass[set.size()]);
Tôi đã viết những điều dưới đây từ những lời khuyên ở trên - ăn cắp nó ... thật tuyệt!
/**
* Handy conversion to set
*/
public class SetUtil {
/**
* Convert some items to a set
* @param items items
* @param <T> works on any type
* @return a hash set of the input items
*/
public static <T> Set<T> asSet(T ... items) {
return Stream.of(items).collect(Collectors.toSet());
}
}
Hiện đã có rất nhiều câu trả lời tuyệt vời đã có, nhưng hầu hết trong số họ sẽ không làm việc với mảng nguyên thủy (như int[]
, long[]
, char[]
, byte[]
, vv)
Trong Java 8 trở lên, bạn có thể đóng hộp mảng với:
Integer[] boxedArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);
Sau đó chuyển đổi thành thiết lập bằng cách sử dụng luồng:
Stream.of(boxedArr).collect(Collectors.toSet());
Đôi khi sử dụng một số thư viện tiêu chuẩn giúp rất nhiều. Hãy thử nhìn vào Bộ sưu tập Apache Commons . Trong trường hợp này, các vấn đề của bạn chỉ đơn giản là chuyển thành một cái gì đó như thế này
String[] keys = {"blah", "blahblah"}
Set<String> myEmptySet = new HashSet<String>();
CollectionUtils.addAll(pythonKeywordSet, keys);
Và đây là bộ sưu tập javadoc
java.util.Collections.addAll(myEmptySet, keys);
??
Sử dụng CollectionUtils
hoặc ArrayUtils
từstanford-postagger-3.0.jar
import static edu.stanford.nlp.util.ArrayUtils.asSet;
or
import static edu.stanford.nlp.util.CollectionUtils.asSet;
...
String [] array = {"1", "q"};
Set<String> trackIds = asSet(array);
Trong Java 10 :
String[] strs = {"A", "B"};
Set<String> set = Set.copyOf(Arrays.asList(strs));
Set.copyOf
trả về một giá trị không thể thay đổi Set
có chứa các phần tử đã cho Collection
.
Cái đã cho Collection
không được null
, và nó không được chứa bất kỳ null
yếu tố nào .
private Map<Integer, Set<Integer>> nobreaks = new HashMap();
nobreaks.put(1, new HashSet(Arrays.asList(new int[]{2, 4, 5})));
System.out.println("expected size is 3: " +nobreaks.get(1).size());
đầu ra là
expected size is 3: 1
thay đổi nó thành
nobreaks.put(1, new HashSet(Arrays.asList( 2, 4, 5 )));
đầu ra là
expected size is 3: 3
Đối với bất cứ ai giải quyết cho Android:
Dấu hoa thị *
là spread
toán tử. Nó áp dụng tất cả các phần tử trong một bộ sưu tập riêng lẻ, từng phần được truyền vào một vararg
tham số phương thức. Nó tương đương với:
val myArray = arrayOf("data", "foo")
val mySet = setOf(*myArray)
// Equivalent to
val mySet = setOf("data", "foo")
// Multiple spreads ["data", "foo", "bar", "data", "foo"]
val mySet = setOf(*myArray, "bar", *myArray)
Vượt qua không có tham số setOf()
dẫn đến một tập hợp trống.
Ngoài ra setOf
, bạn cũng có thể sử dụng bất kỳ trong số này cho một loại băm cụ thể:
hashSetOf()
linkedSetOf()
mutableSetOf()
sortableSetOf()
Đây là cách xác định loại mục bộ sưu tập một cách rõ ràng.
setOf<String>()
hashSetOf<MyClass>()
new HashSet<Object>(Arrays.asList(Object[] a));
Nhưng tôi nghĩ rằng điều này sẽ hiệu quả hơn:
final Set s = new HashSet<Object>();
for (Object o : a) { s.add(o); }
HashSet
được đặt dựa trên kích thước của mảng.
Set<T> b = new HashSet<>(Arrays.asList(requiredArray));