私はArrayList<String>
を持っています、そしてそれから繰り返し文字列を削除したいです。これどうやってするの?
Collection
で重複を避けたい場合は、なぜ重複を許可するCollection
を使用しているのかを考慮する必要があります。重複した要素を削除する最も簡単な方法は、内容をSet
に追加し(重複は許可されません)、Set
をArrayList
に追加することです。
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
もちろん、これはArrayList
の要素の順序を破壊します。
ArrayList
をHashSet
に変換すると重複が効果的に削除されますが、挿入順を維持する必要がある場合は、このバリアントを使用することをお勧めします。
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
その後、List
参照を取り戻す必要がある場合は、変換コンストラクターをもう一度使用できます。
Java 8の場合:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
リストメンバーの hashCode-equals コントラクトは、フィルタリングが正しく機能するために尊重されるべきであることに注意してください。
重複したくない場合は、List
の代わりに Set を使用してください。 List
をSet
に変換するには、次のコードを使用できます。
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
本当に必要な場合は、同じ構造を使用してSet
をList
に戻すことができます。
次のようなString
のリストがあるとします。
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
そうすれば、重複する要素をさまざまな方法で削除できます。
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
注:挿入順を維持したい場合は、LinkedHashSet
の代わりにHashSet
を使用する必要があります。
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
注:特定のリストの実装で結果を収集したい場合。 LinkedList
すると、上記の例を次のように修正できます。
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
上記のコードでもparallelStream
を使用できますが、期待されるパフォーマンス上の利点が得られない可能性があります。これをチェックしてください 質問 もっと。
これはあなたのリストの順番に影響を与えない方法です:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext()) {
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1は元のリスト、l2は繰り返し項目を含まないリストです(等価性を保つために、YourClassにequalsメソッドがあることを確認してください)。
このようにして順序を維持することもできます。
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
Java 8ストリームは、リストから重複する要素を削除するための非常に簡単な方法を提供します。別の方法を使用する都市のリストがあり、そのリストから重複を削除したい場合は、1行で実行できます -
List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");
cityList = cityList.stream().distinct().collect(Collectors.toList());
オプションとして ImmutableSet
from Guava もあります( here はドキュメントです):
ImmutableSet.copyOf(list);
HashSet または もう1つのアレイリスト を使用せずに、重複リストをアレイリストから削除することは可能です。
このコードを試してください。
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
出力は
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
これで問題を解決できます。
private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {
Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
おそらく少しやり過ぎですが、私はこの種の孤立した問題を楽しんでいます。 :)
このコードは一時的なSet(一意性検査用)を使用しますが、元のリスト内の要素を直接削除します。 ArrayList内の要素を削除すると、大量の配列のコピーが発生する可能性があるため、remove(int)メソッドは避けてください。
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
我々がそれをしている間、これがLinkedListのためのバージョンです(ずっと良いです!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Listの統一解を提示するには、マーカーインタフェースを使用します。
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
編集:私は一般的なものは本当にここでは何の価値も追加しないと思います。 :)
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
サードパーティーのライブラリーを使用したい場合は、 Eclipse Collections (以前のGS Collections)のメソッドdistinct()
を使用できます。
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
Setに変換してからListに戻す代わりにdistinct()
を使用する利点は、distinct()
が元のListの順序を保持し、各要素の最初の出現を保持することです。これはSetとListの両方を使って実装されています。
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
元のListをEclipseのCollections型に変換できない場合は、ListAdapterを使用して同じAPIを取得できます。
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
注: 私はEclipseコレクションのコミッターです。
この3行のコードで、ArrayListまたは任意のコレクションから重複した要素を削除できます。
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");
HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
コード:
List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);
注: 間違いなく、メモリのオーバーヘッドが発生します。
これはsetやhashmapのような他のデータ構造を使わない私のコードです。
for(int i = 0; i < Models.size(); i++) {
for(int j = i + 1; j < Models.size(); j++) {
if(Models.get(i).getName().equals(Models.get(j).getName())){
Models.remove(j);
j--;
}
}
}
ArrayListに値を入力するときは、各要素に条件を使用してください。例えば:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
配列{0、1、2、3、4、5、6、7、8、9、10}を取得します。
あなたの注文を保存したいのなら、 LinkedHashSet を使うのが最善です。それを繰り返してこのリストを挿入クエリに渡したい場合は、順序は保持されます。
これを試して
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
この変換は、Listを返すがSetを返さない場合に非常に役立ちます。
LinkedHashSetがトリックを行います。
String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);
System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());
// output:5,1,2,3,4
List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);
output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
これはカスタムオブジェクトリストに使用されます。
public List<Contact> removeDuplicates(List<Contact> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
return 0;
}
return 1;
}
});
set.addAll(list);
final List newList = new ArrayList(set);
return newList;
}
次のようにネストループを使うことができます。
ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();
Iterator iterator1 = l1.iterator();
boolean repeated = false;
while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}
前述のように、要素の統一性を確実にするために、Listの代わりにSetインタフェースを実装するクラスを使用する必要があります。要素の順序を守る必要がある場合は、SortedSetインターフェイスを使用できます。 TreeSetクラスはそのインタフェースを実装します。
import Java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}
for(int a=0;a<myArray.size();a++){
for(int b=a+1;b<myArray.size();b++){
if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
myArray.remove(b);
dups++;
b--;
}
}
}
時間の複雑さ:O(n):設定なし
private static void removeDup(ArrayList<String> listWithDuplicateElements) {
System.out.println(" Original Duplicate List :" + listWithDuplicateElements);
List<String> listWithoutDuplicateElements = new ArrayList<>(listWithDuplicateElements.size());
listWithDuplicateElements.stream().forEach(str -> {
if (listWithoutDuplicateElements.indexOf(str) == -1) {
listWithoutDuplicateElements.add(str);
}
});
System.out.println(" Without Duplicate List :" + listWithoutDuplicateElements);
}
Set<String> strSet = strList.stream().collect(Collectors.toSet());
重複を削除する最も簡単な方法です。
これは正しいものです(HashSetのオーバーヘッドが心配な場合)。
public static ArrayList<String> removeDuplicates (ArrayList<String> arrayList){
if (arrayList.isEmpty()) return null; //return what makes sense for your app
Collections.sort(arrayList, String.CASE_INSENSITIVE_ORDER);
//remove duplicates
ArrayList <String> arrayList_mod = new ArrayList<>();
arrayList_mod.add(arrayList.get(0));
for (int i=1; i<arrayList.size(); i++){
if (!arrayList.get(i).equals(arrayList.get(i-1))) arrayList_mod.add(arrayList.get(i));
}
return arrayList_mod;
}
このようなものがうまくいくでしょうか。
public static void removeDuplicates(ArrayList<String> list) {
Arraylist<Object> ar = new Arraylist<Object>();
Arraylist<Object> tempAR = new Arraylist<Object>();
while (list.size()>0){
ar.add(list(0));
list.removeall(Collections.singleton(list(0)));
}
list.addAll(ar);
}
それは順番を維持し、実行時に二次式でもないはずです。
public Set<Object> findDuplicates(List<Object> list) {
Set<Object> items = new HashSet<Object>();
Set<Object> duplicates = new HashSet<Object>();
for (Object item : list) {
if (items.contains(item)) {
duplicates.add(item);
} else {
items.add(item);
}
}
return duplicates;
}
あなたのリストが自動的に重複を無視してその順序を保存したい場合は、 HashList (HashMapの埋め込みリスト)を作成することができます。
public static class HashList<T> extends ArrayList<T>{
private HashMap <T,T> hashMap;
public HashList(){
hashMap=new HashMap<>();
}
@Override
public boolean add(T t){
if(hashMap.get(t)==null){
hashMap.put(t,t);
return super.add(t);
}else return false;
}
@Override
public boolean addAll(Collection<? extends T> c){
HashList<T> addup=(HashList<T>)c;
for(int i=0;i<addup.size();i++){
add(addup.get(i));
}return true;
}
}
Usage Example:
HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);
あなたがArrayListから重複を削除したい場合は、以下のロジックを見つけることを意味し、
public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}
for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}
long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}
ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");
for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);
if(b==unique.add(value))
dup.add(value);
else
unique.add(value);
}
System.out.println(unique);
System.out.println(dup);
これは、setやhashmapなどのような他のデータ構造を使わずに私の答えです。
public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) {
ArrayList <T> uniqueArrayList = new ArrayList<T>();
for (int i = 0; i < myList.size(); i++){
if (!uniqueArrayList.contains(myList.get(i))){
uniqueArrayList.add(myList.get(i));
}
}
return uniqueArrayList;
}
@ jonathan-staffordソリューションは問題ありません。しかし、これはリストの順番を保存しません。
リストの順番を保存したい場合は、これを使用する必要があります。
public static <T> void removeDuplicate(List <T> list) {
Set <T> set = new HashSet <T>();
List <T> newList = new ArrayList <T>();
for (Iterator <T>iter = list.iterator(); iter.hasNext(); ) {
Object element = iter.next();
if (set.add((T) element))
newList.add((T) element);
}
list.clear();
list.addAll(newList);
}
答えを完成させるだけです。とても良い!