Как в строке одновременно заменить "." на "!" и "!" на "."

Я решил попробовать заменить все точки в строке на ! и одновременно наоборот( т.е ".!.!" -> "!.!."), но не очень понимаю , как это сделать и возможно ли это вообще.

Пробовал сделать это через .replace()


Ответы (6 шт):

Автор решения: Sergey Zh.

Можно, например, через стримы

допустим, s - это строка, тогда новая строка:

Stream.iterate(0, i -> i + 1)
        .limit(s.length())
        .map(x -> s.charAt(x) == '.' ? '!' : (s.charAt(x) == '!' ? '.' : s.charAt(x)))
        .map(x -> x.toString())
        .collect(Collectors.joining());
→ Ссылка
Автор решения: Qwertiy

Небольшое извращение с регулярками, асимптотика квадратичная: https://ideone.com/prUYqn

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone {
  public static void main (String[] args) throws java.lang.Exception {
    var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";
    var res = (str + ".!").replaceAll("..$|\\.(?=.*?(!))|!(?=.*(\\.))", "$1$2");
    
    System.out.println(str);
    System.out.println(res);
  }
}
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
→ Ссылка
Автор решения: Qwertiy

Нормальный вариант с регулярками: https://ideone.com/02Z0vQ

import java.util.*;
import java.util.regex.*;
import java.lang.*;
import java.io.*;

class Ideone {
  public static void main (String[] args) throws java.lang.Exception {
    var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";

    var res = Pattern.compile("[.!]").matcher(str)
              .replaceAll(m -> m.group().equals(".") ? "!" : ".");
    
    System.out.println(str);
    System.out.println(res);
  }
}
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
→ Ссылка
Автор решения: USER1111

Также предложу свой вариант:

String s = ".!.!.!...!";

s = s.replaceAll("\\.", ",").replaceAll("!", ".").replaceAll(",", "!");

P. S в первом replaceAll, там два слеша

→ Ссылка
Автор решения: Qwertiy

Если хочется попридумывать алгоритмы: https://ideone.com/Y2BLPt

import java.util.*;
import java.util.regex.*;
import java.lang.*;
import java.io.*;

class Ideone {
  public static void main (String[] args) throws java.lang.Exception {
    var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";

    var res = str
      .replaceAll("\\.", "..")
      .replaceAll("!", ".!")
      .replaceAll("\\.\\.", "!")
      .replaceAll("\\.!", ".")
    ;
    
    System.out.println(str);
    System.out.println(res);
  }
}
a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!
→ Ссылка
Автор решения: Alex Rudenko

нормальный алгоритм с преобразованием в массив char'ов, циклом и созданием строки:

var str = "a.b.c..d..!..e!!...!!!f....!!.!!!...";
var arr = str.toCharArray();
for (int i = 0, n = arr.length; i < n; i++) {
    if (arr[i] == '!') {
        arr[i] = '.';
    } else if (arr[i] == '.') {
        arr[i] = '!';
    }
}
var rep = new String(arr);
System.out.println(str);
System.out.println(rep);

Результат:

a.b.c..d..!..e!!...!!!f....!!.!!!...
a!b!c!!d!!.!!e..!!!...f!!!!..!...!!!

Если нужно преобразовывать не два, а больше символов, можно использовать switch вместо if / else if:

// Java 12+
static String replacer(String str) {
    if (null == str || str.isEmpty()) return str;

    var arr = str.toCharArray();
    for (int i = 0, n = arr.length; i < n; i++) {
        arr[i] = switch(arr[i]) {
            case '.' -> '!';
            case '!' -> '.';
            default  -> arr[i];
        };
    }
    return new String(arr);
}

или карту символов со стримами :)

static final Map<Character, Character> MAP = Map.of(
    '.', '!',
    '!', '.'
);

static String convert(String str) {
    if (null == str || str.isEmpty()) return str;
    
    return str.chars() // IntStream
        .mapToObj(c -> MAP.getOrDefault((char) c, (char) c)) // Stream<Character>
        .collect(Collector.of( // идиома для преобразования Stream<Character> в String
            StringBuilder::new, (bld, c) -> bld.append(c.charValue()), 
            StringBuilder::append, StringBuilder::toString
        )); 
}

→ Ссылка