find()
рассмотрит подстроку относительно регулярного выражения, где в качестве matches()
рассмотрит полное выражение.
find()
вернет true, только если подстрока выражения совпадает с шаблоном.
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d");
String candidate = "Java123";
Matcher m = p.matcher(candidate);
if (m != null){
System.out.println(m.find());//true
System.out.println(m.matches());//false
}
}
HashSet
хорошее решение А непосредственной проблемы чтения файла в ArrayList
с ограничением уникальности должно просто сохранить HashSet
из замеченных объектов. Прежде, чем обработать строку, мы проверяем, что ее ключ уже не находится в наборе. Если это не, мы добавляем ключ к набору, чтобы отметить его, как закончено, затем добавить данные строки к результату ArrayList
.
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args)
throws FileNotFoundException, IOException {
String file = "prova.txt";
ArrayList<String[]> data = new ArrayList<>();
HashSet<String> seen = new HashSet<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
for (String line; (line = br.readLine()) != null;) {
String[] split = line.split("\\s+");
String key = split[0] + " " + split[1];
if (!seen.contains(key)) {
data.add(Arrays.copyOfRange(split, 2, split.length));
seen.add(key);
}
}
}
for (String[] row : data) {
System.out.println(Arrays.toString(row));
}
}
}
<час> LinkedHashMap
/ LinkedHashSet
, Так как у нас есть пары "ключ-значение" в этом конкретном наборе данных, мы могли прокрутиться, все в LinkedHashMap<String, ArrayList<String>>
( видят документы для [1 111] ), который сохраняет упорядочивание, но не может быть индексирован в (пример использования управляемое решение, но составляет ту же стратегию как выше. ArrayList<String>
или String[]
произвольно здесь - это могло быть любое значение данных). Обратите внимание, что эта версия помогает сохранить последний раз замеченный ключ, а не самое старое (удалите эти !data.containsKey(key)
тест).
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args)
throws FileNotFoundException, IOException {
String file = "prova.txt";
LinkedHashMap<String, ArrayList<String>> data = new LinkedHashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
for (String line; (line = br.readLine()) != null;) {
String[] split = line.split("\\s+");
String key = split[0] + " " + split[1];
if (!data.containsKey(key)) {
ArrayList<String> val = new ArrayList<>();
String[] sub = Arrays.copyOfRange(split, 2, split.length);
Collections.addAll(val, sub);
data.put(key, val);
}
}
}
for (Map.Entry<String, ArrayList<String>> e : data.entrySet()) {
System.out.println(e.getKey() + " => " + e.getValue());
}
}
}
<час> ArrayListSet
вышеупомянутые примеры представляют довольно узкие варианты использования. Вот эскиз для генерала ArrayListSet
класс, который поддерживает обычное поведение списка (add
/ set
/ remove
и т.д.) при сохранении уникальности.
В основном, класс является абстракцией решения № 1 в этом сообщении (HashSet
объединенный с [1 121]), но с немного отличающейся разновидностью (сами данные используются для определения уникальности, а не ключа, но это - более истинное" ArrayList
" структура).
Этот класс решает проблемы эффективности (ArrayList#contains
, линейно, таким образом, мы должны отклонить то решение кроме тривиальных случаев), отсутствие упорядочивания (хранящий, все непосредственно в HashSet
не помогает нам), отсутствие [1 125] операции ( LinkedHashSet
иначе лучшее решение, но мы не можем индексировать в него, таким образом, это не истинная замена для ArrayList
).
Используя HashMap<E, index>
вместо HashSet
убыстрился бы remove(Object o)
и indexOf(Object o)
функции (но замедлился бы sort
). Линейным remove(Object o)
является основной недостаток по плоскости HashSet
.
import java.util.*;
public class ArrayListSet<E> implements Iterable<E>, Set<E> {
private ArrayList<E> list;
private HashSet<E> set;
public ArrayListSet() {
list = new ArrayList<>();
set = new HashSet<>();
}
public boolean add(E e) {
return set.add(e) && list.add(e);
}
public boolean add(int i, E e) {
if (!set.add(e)) return false;
list.add(i, e);
return true;
}
public void clear() {
list.clear();
set.clear();
}
public boolean contains(Object o) {
return set.contains(o);
}
public E get(int i) {
return list.get(i);
}
public boolean isEmpty() {
return list.isEmpty();
}
public E remove(int i) {
E e = list.remove(i);
set.remove(e);
return e;
}
public boolean remove(Object o) {
if (set.remove(o)) {
list.remove(o);
return true;
}
return false;
}
public boolean set(int i, E e) {
if (set.contains(e)) return false;
set.add(e);
set.remove(list.set(i, e));
return true;
}
public int size() {
return list.size();
}
public void sort(Comparator<? super E> c) {
Collections.sort(list, c);
}
public Iterator<E> iterator() {
return list.iterator();
}
public boolean addAll(Collection<? extends E> c) {
int before = size();
for (E e : c) add(e);
return size() == before;
}
public boolean containsAll(Collection<?> c) {
return set.containsAll(c);
}
public boolean removeAll(Collection<?> c) {
return set.removeAll(c) && list.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return set.retainAll(c) && list.retainAll(c);
}
public Object[] toArray() {
return list.toArray();
}
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < list.size() - 1; i++) {
sb.append(list.get(i) + ", ");
}
if (!list.isEmpty()) {
sb.append(list.get(list.size() - 1));
}
sb.append("]");
return sb.toString();
}
}
использование В качестве примера:
public class ArrayListSetDriver {
public static void main(String[] args) {
ArrayListSet<String> fruit = new ArrayListSet<>();
fruit.add("apple");
fruit.add("banana");
fruit.add("kiwi");
fruit.add("strawberry");
fruit.add("apple");
fruit.add("strawberry");
for (String item : fruit) {
System.out.print(item + " "); // => apple banana kiwi strawberry
}
fruit.remove("kiwi");
fruit.remove(1);
fruit.add(0, "banana");
fruit.set(2, "cranberry");
fruit.set(0, "cranberry");
System.out.println();
for (int i = 0; i < fruit.size(); i++) {
System.out.print(fruit.get(i) + " "); // => banana apple cranberry
}
System.out.println();
}
}
Если Вы хотите составить список с уникальными значениями из существующего списка, можно использовать
List myUniqueList = myList.stream().distinct().collect(Collectors.toList());