Вы должны использовать обозначение квадратной скобки, когда -
var ob = {
1: 'One',
7 : 'Seven'
}
ob.7 // SyntaxError
ob[7] // "Seven"
var ob = {
'This is one': 1,
'This is seven': 7,
}
ob.'This is one' // SyntaxError
ob['This is one'] // 1
var ob = {
'One': 1,
'Seven': 7,
}
var _Seven = 'Seven';
ob._Seven // undefined
ob[_Seven] // 7
Простейший: сбрасывает всю коллекцию в Set (используя конструктор Set (Collection) или Set.addAll), а затем посмотрите, имеет ли Set тот же размер, что и ArrayList.
List<Integer> list = ...;
Set<Integer> set = new HashSet<Integer>(list);
if(set.size() < list.size()){
/* There are duplicates */
}
Обновить : Если я правильно понимаю ваш вопрос, у вас есть 2d-массив Block, как в
Block table [] [];
, и вы хотите определить,
В этом случае я мог бы сделать следующее, считая, что Block реализует «equals» и «hashCode» правильно:
for (Block[] row : table) {
Set set = new HashSet<Block>();
for (Block cell : row) {
set.add(cell);
}
if (set.size() < 6) { //has duplicate
}
}
Я не на 100% уверен в синтаксисе, поэтому было бы безопаснее записать его как
for (int i = 0; i < 6; i++) {
Set set = new HashSet<Block>();
for (int j = 0; j < 6; j++)
set.add(table[i][j]);
...
Улучшен код с использованием возвращаемого значения Set#add
вместо сравнения размера списка и набора.
public static <T> boolean hasDuplicate(Iterable<T> all) {
Set<T> set = new HashSet<T>();
// Set#add returns false if the set does not change, which
// indicates that a duplicate element has been added.
for (T each: all) if (!set.add(each)) return true;
return false;
}
Set<T> set = new HashSet<T>(list.size());
? Учитывая параметр «Список», я считаю, что он более эффективен, если в списке нет общих дубликатов.
– Paul Jackson
28 April 2014 в 23:50
HashSet
до размера списка приведет к изменению размера при прохождении по всему списку из-за базового коэффициента загрузки хэш-структуры.
– Jay Anderson
22 March 2018 в 22:19
String tempVal = null;
for (int i = 0; i < l.size(); i++) {
tempVal = l.get(i); //take the ith object out of list
while (l.contains(tempVal)) {
l.remove(tempVal); //remove all matching entries
}
l.add(tempVal); //at last add one entry
}
Примечание: это будет иметь большую производительность, хотя, поскольку элементы удаляются из начала списка. Чтобы решить эту проблему, у нас есть два варианта. 1) итерация в обратном порядке и удаление элементов. 2) Используйте LinkedList вместо ArrayList. Из-за необъективных вопросов, заданных в интервью, чтобы удалить дубликаты из списка без использования какой-либо другой коллекции, приведенным выше примером является ответ. В реальном мире, хотя, если я должен достигнуть этого, я положу элементы из списка в Set, просто!
Проще говоря: 1) убедитесь, что все элементы сопоставимы. 2) Сортируйте массив. 2) итерации по массиву и поиска дубликатов
/**
* Method to detect presence of duplicates in a generic list.
* Depends on the equals method of the concrete type. make sure to override it as required.
*/
public static <T> boolean hasDuplicates(List<T> list){
int count = list.size();
T t1,t2;
for(int i=0;i<count;i++){
t1 = list.get(i);
for(int j=i+1;j<count;j++){
t2 = list.get(j);
if(t2.equals(t1)){
return true;
}
}
}
return false;
}
Пример конкретного класса, который переопределил equals()
:
public class Reminder{
private long id;
private int hour;
private int minute;
public Reminder(long id, int hour, int minute){
this.id = id;
this.hour = hour;
this.minute = minute;
}
@Override
public boolean equals(Object other){
if(other == null) return false;
if(this.getClass() != other.getClass()) return false;
Reminder otherReminder = (Reminder) other;
if(this.hour != otherReminder.hour) return false;
if(this.minute != otherReminder.minute) return false;
return true;
}
}
Улучшенный код для возврата повторяющихся элементов
public static <T> List getDuplicate(Collection<T> list) {
final List<T> duplicatedObjects = new ArrayList<T>();
Set<T> set = new HashSet<T>() {
@Override
public boolean add(T e) {
if (contains(e)) {
duplicatedObjects.add(e);
}
return super.add(e);
}
};
for (T t : list) {
set.add(t);
}
return duplicatedObjects;
}
public static <T> boolean hasDuplicate(Collection<T> list) {
if (getDuplicate(list).isEmpty())
return false;
return true;
}
Мне нужно было выполнить аналогичную операцию для Stream
, но не удалось найти хороший пример. Вот что я придумал.
public static <T> boolean areUnique(final Stream<T> stream) {
final Set<T> seen = new HashSet<>();
return stream.allMatch(seen::add);
}
Это имеет преимущество короткого замыкания, когда дубликаты найдены раньше, чем обрабатывать весь поток и не намного сложнее, чем просто положить все в a Set
и проверить размер. Таким образом, этот случай будет примерно таким:
List<T> list = ...
boolean allDistinct = areUnique(list.stream());
Если вы хотите избежать дублирования вообще, вам следует просто вырезать средний процесс обнаружения дубликатов и использовать Set .
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class FindDuplicateInArrayList {
public static void main(String[] args) {
Set<String> uniqueSet = new HashSet<String>();
List<String> dupesList = new ArrayList<String>();
for (String a : args) {
if (uniqueSet.contains(a))
dupesList.add(a);
else
uniqueSet.add(a);
}
System.out.println(uniqueSet.size() + " distinct words: " + uniqueSet);
System.out.println(dupesList.size() + " dupesList words: " + dupesList);
}
}
Чтобы знать дубликаты в списке, используйте следующий код: он даст вам набор, содержащий дубликаты.
public Set<?> findDuplicatesInList(List<?> beanList) {
System.out.println("findDuplicatesInList::"+beanList);
Set<Object> duplicateRowSet=null;
duplicateRowSet=new LinkedHashSet<Object>();
for(int i=0;i<beanList.size();i++){
Object superString=beanList.get(i);
System.out.println("findDuplicatesInList::superString::"+superString);
for(int j=0;j<beanList.size();j++){
if(i!=j){
Object subString=beanList.get(j);
System.out.println("findDuplicatesInList::subString::"+subString);
if(superString.equals(subString)){
duplicateRowSet.add(beanList.get(j));
}
}
}
}
System.out.println("findDuplicatesInList::duplicationSet::"+duplicateRowSet);
return duplicateRowSet;
}
лучший способ справиться с этой проблемой - использовать HashSet:
ArrayList<String> listGroupCode = new ArrayList<>();
listGroupCode.add("A");
listGroupCode.add("A");
listGroupCode.add("B");
listGroupCode.add("C");
HashSet<String> set = new HashSet<>(listGroupCode);
ArrayList<String> result = new ArrayList<>(set);
Просто напечатать результирующий арифметик и увидеть результат без дубликатов:)
ArrayList<String> withDuplicates = new ArrayList<>();
withDuplicates.add("1");
withDuplicates.add("2");
withDuplicates.add("1");
withDuplicates.add("3");
HashSet<String> set = new HashSet<>(withDuplicates);
ArrayList<String> withoutDupicates = new ArrayList<>(set);
ArrayList<String> duplicates = new ArrayList<String>();
Iterator<String> dupIter = withDuplicates.iterator();
while(dupIter.hasNext())
{
String dupWord = dupIter.next();
if(withDuplicates.contains(dupWord))
{
duplicates.add(dupWord);
}else{
withoutDupicates.add(dupWord);
}
}
System.out.println(duplicates);
System.out.println(withoutDupicates);
Если ваши элементы каким-то образом сопоставимы (тот факт, что порядок имеет какой-либо реальный смысл, равнодушен - он просто должен соответствовать вашему определению равенства), самое быстрое решение для удаления дубликатов собирается сортировать список (0 ( n log (n))), затем выполнить один проход и искать повторяющиеся элементы (то есть равные элементы, которые следуют друг за другом) (это O (n)).
Общая сложность будет O (n log (n)), что примерно совпадает с тем, что вы получите с помощью Set (n times long (n)), но с гораздо меньшей константой. Это связано с тем, что константа в sort / dedup возникает из-за стоимости сравнения элементов, тогда как стоимость из набора, скорее всего, будет результатом вычисления хеша, плюс одно (возможно, несколько) хеш-сравнений. Если вы используете реализацию Set на основе хэша, то есть потому, что Tree based даст вам O (n log² (n)), что еще хуже.
Как я понимаю, однако вам не нужно удалить дубликаты, а просто проверить их существование. Таким образом, вы должны вручную скомпилировать алгоритм сортировки слияния или кучи в своем массиве, который просто выдает возвращаемое значение true (т. Е. «Есть дубликат»), если ваш компаратор возвращает 0 и в противном случае завершает сортировку и проходит проверку отсортированного массива для повторов , В случае слияния или кучи, действительно, когда сортировка будет завершена, вы будете сравнивать каждую повторяющуюся пару, если оба элемента уже не находятся в их конечных положениях (что маловероятно). Таким образом, алгоритм выборочной сортировки должен дать огромное повышение производительности (я должен был бы это доказать, но, я думаю, алгоритм с измененным алгоритмом должен быть в O (log (n)) на равномерно случайных данных)