Как добавить элементы одного набора к элементам другого набора с использованием Java 7
У меня есть 2 набора:
Set<String> set1 = new TreeSet<String>();
Set<String> set2 = new TreeSet<String>();
Set<String> set3 = new TreeSet<String>();
set1 = [A, C, E];
set2 = [B, D, F];
Я ищу способ добавить значение set2
в set1
и сохранить их в set3
Установить 3 Выход
set3 = [AB, CD, EF]
Ответы
Ответ 1
Вам нужно использовать Iterator
, чтобы сохранить порядок TreeSet
. Вы можете получить его, позвонив TreeSet.iterator()
:
Возвращает итератор по элементам в этом наборе в порядке возрастания.
Предполагая, что оба набора имеют одинаковую длину, вы могли бы:
public static void main(String[] args) {
Set<String> set1 = new TreeSet<String>(Arrays.asList("A", "C", "E"));
Set<String> set2 = new TreeSet<String>(Arrays.asList("B", "D", "F"));
Set<String> set3 = new TreeSet<String>();
Iterator<String> it1 = set1.iterator();
Iterator<String> it2 = set2.iterator();
while (it1.hasNext() && it2.hasNext()) {
set3.add(it1.next() + it2.next());
}
System.out.println(set3); // prints "[AB, CD, EF]"
}
Если набор имеет разный размер и это ошибка, вы можете добавить следующую проверку перед циклом while
:
if (set1.size() != set2.size()) {
throw new IllegalArgumentException("Can't merge sets of different size");
}
Для справки вы можете сделать это, используя Java 8, используя утилиту zip
из этого ответа:
Set<String> set3 = zip(set1.stream(), set2.stream(), String::concat)
.collect(Collectors.toCollection(TreeSet::new));
Ответ 2
Вот способ сделать это императивным способом, с Java 7:
Set<String> set1 = new TreeSet<String>(Arrays.asList(new String[]{"A", "C", "E"}));
Set<String> set2 = new TreeSet<String>(Arrays.asList(new String[]{"B", "D", "F"}));
Set<String> set3 = new TreeSet<String>();
// Java 7: imperative
// edit: checking sizes beforehand
if (set1.size() != set2.size())
throw new IllegalStateException("Sets aren't the same size!");
Iterator<String> iterator1 = set1.iterator();
Iterator<String> iterator2 = set2.iterator();
while (iterator1.hasNext()) {
String s = iterator1.next();
// assuming iterator2.hasNext() as sizes were checked previously
s = s.concat(iterator2.next());
set3.add(s);
}
System.out.println(set3);
Выход
[AB, CD, EF]
Вариант Java 8 с функциональной идиомой (немного уродливой)
// Java 8: functional (but ugly)
Iterator<String> iterator2new = set2.iterator();
// edited, ensuring a `TreeSet` is returned
set3 =
set1
.stream()
.map((s) -> s.concat(iterator2new.next()))
.collect(Collectors.toCollection(TreeSet::new));
System.out.println(set3);
Выход
[AB, CD, EF]
Ответ 3
Другой способ сделать это - использовать библиотеку, которая добавляет zip
в Java 8 streams
, например https://github.com/poetix/protonpack или https://github.com/jOOQ/jOOL
Ответ 4
Мне очень не нравится while (it1.hasNext())
, поэтому мои способы:
1)
Iterator<String> iterator2 = set2.iterator();
for(String s : set1) {
set3.add(s.concat(iterator2.next()));
}
System.out.println(set3);
2) или
List<String> list = new ArrayList<String>(set2);
int i = 0;
for(String s : set1) {
set3.add(s.concat(list.get(i)));
i++;
}
System.out.println(set3);
3) (1) с проверкой:
Iterator<String> iterator2 = set2.iterator();
for(String s : set1) {
set3.add(s.concat(iterator2.hasNext()? iterator2.next(): ""));
}
System.out.println(set3);
4) (2) с проверкой:
List<String> list = new ArrayList<String>(set2);
int i = 0;
for(String s : set1) {
set3.add(s.concat(list.size() > i? list.get(i): ""));
i++;
}
System.out.println(set3);